UE4連接第三方庫(lib和dll)

摘要:
寫這個文章主要是被UE官方的wiki和answerhub誤導了好久,這原本是一個很常見和基本的問題,可是不管是官方的wiki或者是論壇上的提問都十分散亂而且充斥各類錯誤,所以記錄下這個在開發中時常遇到的問題。函數

在開發中常常遇到的問題就是加入某第三方庫的支持,這樣的第三方庫每每屬於無源碼,並且多是靜態lib或者是動態dll甚至二者皆有。UE4的編譯管理用的是本身的UBT(unreal binary tool)所以連接第三方庫的工做主要是編寫UBT腳本。ui

1.以插件方式集成.
基本上這個是最推薦的集成第三方庫的方式,由於可以很好的隔離你的代碼和第三方代碼的影響,在UE4的源碼裏也能夠看到不少第三方庫都是這麼集成的,好比paper2D,leapmotion等等。在UE4中新建插件的方式略去不表,當你新建完你的插件以後,你會在插件的代碼目錄下看到一個插件

xxx.build.cs

接下來要作的就是修改這個腳本:code

獲得當前路徑orm

private string ModulePath
{
   get { return ModuleDirectory; }
}

關於第三方庫放的位置,通常是在plugin的源碼同級文件夾下建一個ThirdParty文件夾,裏面放上include lib等等。ci

獲得ThirdParty文件夾的路徑開發

private string ThirdPartyPath
{
        get { return Path.GetFullPath(Path.Combine(ModulePath,"../../ThirdParty/")); }
}

爲工程添加include第三方庫的頭文件路徑
在模快的構造函數里加上:get

PublicIncludePaths.AddRange(
        new string[] { 
             Path.Combine(ThirdPartyPath, "xxx", "Include"),
        }
        );
            
    
PrivateIncludePaths.AddRange(
        new string[] {
            Path.Combine(ThirdPartyPath, "Foxit", "Include"),
        }
        );

連接第三方庫的Lib源碼

接下來須要在編譯工程時加入第三方靜態庫的連接,靜態連接屬於工程在編譯期間作的事情,所以這塊須要經過cs腳本完成,而dll動態連接庫的加載是運行期的事,所以須要在cpp文件中執行。string

咱們新建一個叫LoadxxxLib的函數,並把它放在模塊的構造函數結尾執行:

public bool LoadxxxLib(TargetInfo Target)
    {
        bool isLibararySupported = false;
        if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32))
        {
            isLibararySupported = true;
            string PlatformString = (Target.Platform == UnrealTargetPlatform.Win64) ? "Win64" : "Win32";
            PublicAdditionalLibraries.Add(Path.Combine(LibraryPath, PlatformString + ".lib"));
            PublicDelayLoadDLLs.Add(PlatformString + ".dll");
            RuntimeDependencies.Add(new RuntimeDependency(LibraryPath + PlatformString + ".dll"));
        }
        return isLibararySupported;
    }

這樣就能夠保證在編譯期連接上咱們的第三方lib。

連接動態DLL

這個工做須要在plugin的運行期完成,在插件的source文件下找到一個與插件名字同名的cpp文件打開。會看到一個StartupModule的函數,咱們須要在這裏獲得dll文件的handle。

在StartupModule中添加下面的代碼:

void FXXXModule::StartupModule()
{
#if PLATFORM_64BITS
    FString platform = TEXT("win64.dll");
#else
    FString platform = TEXT("win32.dll");
#endif
    FString path = IPluginManager::Get().FindPlugin("XXX")->GetBaseDir(); 
    FString dllpath = path + "/ThirdParty/XXX/Lib/" + platform;
    PdfDllHandle = FPlatformProcess::GetDllHandle(*dllpath);
    if (!PdfDllHandle)
    {
        UE_LOG(LogTemp, Warning, TEXT("Failed to load PDF library."));
    }
}

這裏咱們用的是PluginManager找到的插件所在的路徑,值得注意的是使用這個函數時須要在build.cs
中加入

PrivateDependencyModuleNames.AddRange(
            new string[]
            {
                ...
                "Projects",
            }
            );

不然工程會連接出錯。

相關文章
相關標籤/搜索