一. 首先要拷貝對應的 第三方庫
bin里有dll動態庫,include里有動態庫需要的頭文件。
二.在Target.cs里,進行設置
頭文件前面的路徑為公共路徑
設置需要一起打包的三方庫文件
三.加載這個庫
FPlatformProcess::GetDllHandle將他解析為 任意類型,用void* 接受。
//加載dllFString tmpDllPath = FPaths::GameSourceDir() + TEXT("LearnProject/BassSDK/bin/x64/bass.dll"); //解析這個庫BassDllHandle = FPlatformProcess::GetDllHandle(*tmpDllPath);if (!BassDllHandle) return;
再用FPlatformProcess::GetDllExport.傳入這個解析出來庫的指針,和你要使用的函數名的TEXT類型,比如TEXT("BASS_Init")。返回也要進行指針轉換,轉換為對應的函數指針。沒想到函數指針在這里居然被用到。
//初始化bassBassInitTOFunc BassInitTO = (BassInitTOFunc)FPlatformProcess::GetDllExport(BassDllHandle, TEXT("BASS_Init")); //拿到這個庫的某個函數(初始化)if (!BassInitTO) return;bool isBassInit = BassInitTO(-1, 44100, 0, NULL, 0);if (!isBassInit) return;
我們用函數指針BassInitTOFunc接住返回值。它的定義如下
typedef BOOL(*BassInitTOFunc)(int, DWORD, DWORD, HWND, const void*);
這里是給 函數指針起了 叫BassInitToFunc的別名。可以看這篇文章的第三部分
C語言指針進階(一)——深入詳解“函數指針”與“指針函數”-CSDN博客
四.來回用庫里的函數達到播放音樂效果
#pragma once#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "bass.h"
#include "DLLManager.generated.h"/*** *///音效
#define AUDIO_BASS_BGM "DiscoFlow.wav"
typedef BOOL(*BassInitTOFunc)(int, DWORD, DWORD, HWND, const void*);
typedef HSTREAM(*BassCreateTOFunc)(BOOL, const void*, QWORD, QWORD, DWORD);
typedef BOOL(*BassPlayTOFunc)(DWORD, BOOL);UCLASS()
class LEARNPROJECT_API UDLLManager : public UObject
{GENERATED_BODY()
public:void InitDLL();//BGMbool PlayBGMTO();void* BassDllHandle;//Bass dllHSTREAM BassBGM;
};
// Fill out your copyright notice in the Description page of Project Settings.#include "DLLManager.h"void UDLLManager::InitDLL()
{//加載dllFString tmpDllPath = FPaths::GameSourceDir() + TEXT("LearnProject/BassSDK/bin/x64/bass.dll"); //解析這個庫BassDllHandle = FPlatformProcess::GetDllHandle(*tmpDllPath);if (!BassDllHandle) return;//初始化bassBassInitTOFunc BassInitTO = (BassInitTOFunc)FPlatformProcess::GetDllExport(BassDllHandle, TEXT("BASS_Init")); //拿到這個庫的某個函數(初始化)if (!BassInitTO) return;bool isBassInit = BassInitTO(-1, 44100, 0, NULL, 0);if (!isBassInit) return;//創建bgm文件流BassCreateTOFunc BassCreateTO = (BassCreateTOFunc)FPlatformProcess::GetDllExport(BassDllHandle, TEXT("BASS_StreamCreateFile")); //拿到這個庫的某個函數(加載流文件)if (BassCreateTO){FString AudioFile = FPaths::GameSourceDir() + TEXT("LearnProject/BassSDK/Audios/") + AUDIO_BASS_BGM;BassBGM = BassCreateTO(FALSE, TCHAR_TO_UTF8(*AudioFile), 0, 0, BASS_SAMPLE_LOOP);}
}bool UDLLManager::PlayBGMTO()
{if (!BassDllHandle) return false;BassPlayTOFunc BassPlayTO = (BassPlayTOFunc)FPlatformProcess::GetDllExport(BassDllHandle, TEXT("BASS_ChannelPlay")); //拿到這個庫的某個函數(單通道播放)if (BassPlayTO)return BassPlayTO(BassBGM, true);return false;
}
測試
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"class UDLLManager;UCLASS()
class LEARNPROJECT_API AMyActor : public AActor
{GENERATED_BODY()public: // Sets default values for this actor's propertiesAMyActor();protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public: // Called every framevirtual void Tick(float DeltaTime) override;//音效管理UPROPERTY()UDLLManager* AudioManager;};
// Fill out your copyright notice in the Description page of Project Settings.#include "MyActor.h"
#include "DLLManager.h"// Sets default values
AMyActor::AMyActor()
{// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;}// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{Super::BeginPlay();AudioManager = NewObject<UDLLManager>(this);if (AudioManager){AudioManager->InitDLL();// AudioManager->InitAudioManager();AudioManager->PlayBGMTO();}
}// Called every frame
void AMyActor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}