一. 首先要拷贝对应的 第三方库
bin里有dll动态库,include里有动态库需要的头文件。
二.在Target.cs里,进行设置
头文件前面的路径为公共路径
设置需要一起打包的三方库文件
三.加载这个库
FPlatformProcess::GetDllHandle将他解析为 任意类型,用void* 接受。
//加载dll
FString tmpDllPath = FPaths::GameSourceDir() + TEXT("LearnProject/BassSDK/bin/x64/bass.dll"); //解析这个库
BassDllHandle = FPlatformProcess::GetDllHandle(*tmpDllPath);
if (!BassDllHandle) return;
再用FPlatformProcess::GetDllExport.传入这个解析出来库的指针,和你要使用的函数名的TEXT类型,比如TEXT("BASS_Init")。返回也要进行指针转换,转换为对应的函数指针。没想到函数指针在这里居然被用到。
//初始化bass
BassInitTOFunc 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();
//BGM
bool PlayBGMTO();
void* BassDllHandle;//Bass dll
HSTREAM BassBGM;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "DLLManager.h"
void UDLLManager::InitDLL()
{
//加载dll
FString tmpDllPath = FPaths::GameSourceDir() + TEXT("LearnProject/BassSDK/bin/x64/bass.dll"); //解析这个库
BassDllHandle = FPlatformProcess::GetDllHandle(*tmpDllPath);
if (!BassDllHandle) return;
//初始化bass
BassInitTOFunc 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 properties
AMyActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual 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);
}