引擎世界丨EngineWorld.CN

标题: 自己总结的ue4集成第三方库的步骤和手段 [打印本页]

作者: Wangwentao1    时间: 2017-2-14 11:27
标题: 自己总结的ue4集成第三方库的步骤和手段
原文发在我的博客:https://segmentfault.com/a/1190000008210614


摘要:
写这个文章主要是被UE官方的wiki和answerhub误导了很久,这本来是一个很常见和基本的问题,但是无论是官方的wiki或者是论坛上的提问都十分散乱并且充斥各种错误,因此记录下这个在开发中时常遇到的问题。
在开发中经常遇到的问题就是加入某第三方库的支持,这样的第三方库往往属于无源码,而且可能是静态lib或者是动态dll甚至两者皆有。UE4的编译管理用的是自己的UBT(unreal binary tool)因此链接第三方库的工作主要是编写UBT脚本。
1.以插件方式集成.
基本上这个是最推荐的集成第三方库的方式,因为能够很好的隔离你的代码和第三方代码的影响,在UE4的源码里也可以看到很多第三方库都是这么集成的,比如paper2D,leapmotion等等。在UE4中新建插件的方式略去不表,当你新建完你的插件之后,你会在插件的代码目录下看到一个


xxx.build.cs接下来要做的就是修改这个脚本:
得到当前路径


private string ModulePath{   get { return ModuleDirectory; }}关于第三方库放的位置,一般是在plugin的源码同级文件夹下建一个ThirdParty文件夹,里面放上include lib等等。
得到ThirdParty文件夹的路径


private string ThirdPartyPath{        get { return Path.GetFullPath(Path.Combine(ModulePath,"../../ThirdParty/")); }}为工程添加include第三方库的头文件路径
在模快的构造函数里加上:


PublicIncludePaths.AddRange(        new string[] {              Path.Combine(ThirdPartyPath, "xxx", "Include"),        }        );                PrivateIncludePaths.AddRange(        new string[] {            Path.Combine(ThirdPartyPath, "Foxit", "Include"),        }        );链接第三方库的Lib
接下来需要在编译工程时加入第三方静态库的链接,静态链接属于工程在编译期间做的事情,因此这块需要通过cs脚本完成,而dll动态链接库的加载是运行期的事,因此需要在cpp文件中执行。
我们新建一个叫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",            }            );            否则工程会链接出错。

作者: __________    时间: 2017-2-14 12:14
感谢分享经验,已mark
作者: qinjiawang    时间: 2017-2-14 12:33
有没有图片啊
作者: Wangwentao1    时间: 2017-2-14 13:22
qinjiawang 发表于 2017-2-14 12:33
有没有图片啊

本来就是代码的活啊 要啥图片
作者: qinjiawang    时间: 2017-2-14 13:48
Wangwentao1 发表于 2017-2-14 13:22
本来就是代码的活啊 要啥图片

好的,感谢
作者: 堕落的牧羊人    时间: 2017-2-14 14:16
谢谢分享
作者: ajhonson4    时间: 2017-2-14 23:42
谢谢分享~~~~~~~
作者: chinabeater    时间: 2017-2-15 08:50
感谢楼主的经验分享,文章里有一点需要纠正的,UBT应该是Unreal Build Tool,虽然这东西无关紧要,但是严谨点总没错。
作者: mxlhy    时间: 2017-2-15 09:57
感谢楼主的经验分享,学习了。
虽然排版没弄好,但这都不是事儿。
作者: kiben4    时间: 2017-2-16 13:48
感谢分享!
作者: 山楂卷    时间: 2017-2-20 14:19
你这样加载dll 还要写两遍,一遍是在CS文件里,另一边还要在代码里加载,太费事了。
我是这样加载的
foreach (string FilePath in Directory.EnumerateFiles(Path.Combine(ModuleDirectory, "../../../Binaries/ThirdParty/XXXX/Win64/"), "*", SearchOption.AllDirectories))
            {
                RuntimeDependencies.Add(new RuntimeDependency(FilePath));
            }
        }

直接把dll 加载了,跟静态一样的。 之后代码里加上头文件直接引用就可以了
作者: Wangwentao1    时间: 2017-2-28 11:23
chinabeater 发表于 2017-2-15 08:50
感谢楼主的经验分享,文章里有一点需要纠正的,UBT应该是Unreal Build Tool,虽然这东西无关紧要,但是严谨 ...

thanks!!!
作者: lyosky    时间: 2017-4-5 13:28
谢谢楼主分享~
作者: Mu林逸    时间: 2017-5-9 12:04
感谢分享,十分有用。
作者: 红泥同学    时间: 2017-9-2 00:16
已收藏,感谢分享




欢迎光临 引擎世界丨EngineWorld.CN (https://www.engineworld.cn/) Powered by Discuz! X3.5