UE4 呼叫第三方庫(C++dll例子)
1.建立工程時選擇Visual C++>Win32,建立的工程名稱為Test。之後在工程引導中選擇DLL和空工程即可。建立完成之後新增新類。此處命名為Test。點選儲存後,設定BuildSetting為Release和x64(對應win64,如果是32為就X86)生成專案,拿到Project/x64/Release下的dll檔案。
2.將lib dll檔案和對應的include檔案考到指定目錄中 通常為專案的Plugins/ThirdParty/Win64 (可自定義,比如放在Source下)
3. 新增到工程中 程式碼如
PublicAdditionalLibraries.Add(lib
PublicIncludePaths.Add(lib標頭檔案目錄);
使用時 在使用的程式碼中直接#include 標頭檔案即可 (有的時候編譯會報兩個連結錯誤 重新編譯一下就好了)
4. 使用dll庫 程式碼如下
需要現在.build.cs中配置
PublicDelayLoadDLLs.Add(dll目錄 + dll檔名);
RuntimeDependencies.Add(new RuntimeDependency(dll目錄 + dll檔名));
如果該dll有依賴的dll 需要將依賴的dll放在 binariesPath
5. dll呼叫
呼叫的方法如下:
假設dll函式原型 int add(int a, int b)
則呼叫程式碼中
typedef int(*AddFunc)(int a, int b);
AddFunc tempFunc;
void* pDllHandler = FPlatformProcess::GetDllHandle(*dll路徑);
if (pDllHandler)
{
FString funcName = "add";
tempFunc = (AddFunc)FPlatformProcess::GetDllExport(pDllHandler, *funcName);
check(tempFunc);
int c = tempFunc(2, 3);
}
注意:
1.連結靜態庫和動態庫不同的是,靜態連結屬於工程在編譯期間做的事情,因此這塊需要通過cs指令碼完成,而dll動態連結庫的載入是執行期的事,因此需要在cpp檔案中執行。
2.生成庫時設定Release和x64(對應win64,如果是32位就X86)。
3.有的dll載入不了裡面的函式,解決:
①編寫庫檔案時加上
//判斷如果是C++編譯器
#ifdef __cplusplus
extern "C"
{
#endif
namespace WindowsOperate
{
class Common
{
public:
static __declspec(dllexport) double TestAdd(double &a, double& _b);
};
}
#ifdef __cplusplus
}
#endif
②編寫庫檔案時另外在原始檔中加上.def模組定義檔案再編譯,
LIBRARY "TestDll"
EXPORTS
TestAdd @1
TestAdd2 @2
如圖:
程式碼示例(UE4):
TestDll.build.cs:
public class TestDll : ModuleRules
{
public TestDll(TargetInfo Target)
{
Type = ModuleType.External;
//新增庫的標頭檔案
PublicIncludePaths.AddRange(
new string[] {
"Win64/include"
// ... add public include paths required here ...
}
);
PrivateIncludePaths.AddRange(
new string[] {
"Win64/include"
// ... add other private include paths required here ...
}
);
string VedioIncludePath = ModuleDirectory + "/Win64/include/";
PublicSystemIncludePaths.Add(VedioIncludePath);
//新增庫的lib
string LibPath = Path.Combine(ThirdPartyPath + "/TestDll/Win64/lib/", "TestDll.lib");
PublicLibraryPaths.Add(LibPath);
PublicAdditionalLibraries.Add(LibPath);
//新增執行時庫的Dll
string DllPath = Path.Combine(ThirdPartyPath + "/TestDll/Win64/dll/", "TestDll.dll");
PublicDelayLoadDLLs.Add("TestDll.dll");
RuntimeDependencies.Add(new RuntimeDependency(DllPath));
}
private string ThirdPartyPath
{
get { return Path.GetFullPath(Path.Combine(ModuleDirectory, "../../ThirdParty/")); }
}
}
cpp:
typedef double(*_dllFun_Add)(double &a, double& _b);
_dllFun_Add t_fun;
void* PdfDllHandle;
FString dllpath = FPaths::GameSourceDir() + "ThirdParty/TestDll/Win64/dll/TestDll.dll";
PdfDllHandle = FPlatformProcess::GetDllHandle(*dllpath);
if (PdfDllHandle!=NULL)
{
FString funName = "TestAdd";
t_fun = (_dllFun_Add)FPlatformProcess::GetDllExport(PdfDllHandle, *funName);
if (t_fun!=NULL)
{
double a1 = 1.2f;
double a2 = 1.3f;
double a3 = t_fun(a1, a2);
}
}
//參考連結,android
//呼叫dll並提供藍圖介面(和wiki的一樣)
https://blog.csdn.net/baidu_27276201/article/details/75675836?locationNum=2&fps=1