摘要:
写这个文章主要是被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",}
        );

链接第三方库的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",}
            );

否则工程会链接出错。

UE4链接第三方库lib和dll的更多相关文章

  1. ios中的.dylib和.a lib有什么区别?

    我知道Objectivec中的编译和运行时是什么,但是我想知道是什么画了这两个库之间的界限?他们的目的是什么,除了陈述一个是静态的而另一个是动态的?我们何时需要一个而不是另一个?

  2. xamarin.ios – ShareKit与MonoTouch如何?

    有人可以验证ShareKit实际上是否可用于MonoTouch并指导我完成使其工作所需的步骤?解决方法您首先从getsharekit.com下载还是使用ShareKit2.0?

  3. ios – iPhone崩溃日志不能正确地符号化并且是双重间隔的

    任何建议超过欢迎.谢谢.解决方法当这件事发生在我身上时,它只是我通过电子邮件收到的日志.如果我记得,至少有一些是在.msg文件中,我不得不把它们拿出来.它可能是Exchange编码更改.如果你显示不可见的字符,你可能会看到每个字符之间的东西.您可以找到并替换它们以删除它们或更改编辑器中的编码.

  4. ios – Xcode 7 beta 2:LaunchScreen.storyboard无法打开文档

    我在两个不同的Mac(iMac和MacBookpro)上收到这个错误.不知道为什么人们不能再现它,但我需要一些帮助.在运行XX优胜美地10.10.4的Mac上运行Xcode7beta2(15六月’15).甚至无法编译和运行我的项目..我从创建菜单创建了一个视图应用程序项目,就是这样.编辑:我试图删除并重新添加storyboard文件(也可以打开Main.storyboard插件),我仍然得到相同的

  5. ios – 为具有多个目标和不同平台的项目编写Podfile

    如何让CocoaPods成功整合到我的项目和iOS/Mac目标?我已经阅读了Podfile文档,但发现它在这方面缺乏.解决方法得到它了!从我的每个目标和运行的pod安装中删除libPods-xxxx.a文件,再次执行了我的目标集成.

  6. ios – 在/usr/lib/system/libcache.dylib中,缺少必需的架构armv6

    在试图为iphoneos编写一个虚拟程序时,Xcode4,gcc似乎没有超出初始的sysroot目录如果我把sysroot,以下作品,但感觉非常干酪,而且不可伸缩.这里发生了什么?

  7. iOS中的CocoaPods是什么?

    任何人都可以详细说明iOS开发中的CocoaPods.我似乎无法理解它们是什么.提前致谢.解决方法CocoaPods是我在最近的iOS应用程序开发中发现的最好的东西之一.我用它来获取最新的Github开源项目作为框架和lib到我的项目中.最好的部分是它将自动管理依赖lib,因此无需拖放文件并下载文件夹blaablaaa只需一个简单的代码’podinstall即可!

  8. Swift 2/iOS 9 – libz.dylib找不到

    我在我的新的Swift2.0项目中使用一些来自google的外部代码,在早期版本中需要“libz.dylib”。更新到新的XCode/新的SDK后。

  9. android – 用我非常简单的calabash测试用例不断得到错误“HTTPClient :: ReceiveTimeoutError”

    我是calabash-android测试自动化库的新手.我花了两天时间来理解这个问题没有成功:(我正在使用calabash-android版本0.8.0,我按照文档pre-definedsteps进行测试.我的测试很简单,只需等待登录界面(这是一个包含id为“email_field”的输入字段的活动),输入用户名和密码.这是我在功能文件中的步骤:当我使用命令calabash-android运行my

  10. phonegap运行android – create命令失败,退出代码8 – linux

    我做了一些googleing但没有发现任何相关内容.任何帮助赞赏.请务必使用裸体vm进行尝试没有nodejs安装或依赖问题.基督教解决方法我刚刚面临同样的问题,问题是没有正确设置sdk工具的路径:请尝试以下方法:

随机推荐

  1. static – 在页面之间共享数据的最佳实践

    我想知道在UWP的页面之间发送像’selectedItem’等变量的最佳做法是什么?创建一个每个页面都知道的静态全局变量类是一个好主意吗?

  2. .net – 为Windows窗体控件提供百分比宽度/高度

    WindowsForm开发的新手,但在Web开发方面经验丰富.有没有办法为Windows窗体控件指定百分比宽度/高度,以便在用户调整窗口大小时扩展/缩小?当窗口调整大小时,可以编写代码来改变控件的宽度/高度,但我希望有更好的方法,比如在HTML/CSS中.在那儿?

  3. 使用Windows Azure查询表存储数据

    我需要使用特定帐户吗?>将应用程序部署到Azure服务后,如何查询数据?GoogleAppEngine有一个数据查看器/查询工具,Azure有类似的东西吗?>您可以看到的sqlExpressintance仅在开发结构中,并且一旦您表示没有等效,所以请小心使用它.>您可以尝试使用Linqpad查询表格.看看JamieThomson的thispost.

  4. windows – SetupDiGetClassDevs是否与文档中的设备实例ID一起使用?

    有没有更好的方法可以使用DBT_DEVICEARRIVAL事件中的数据获取设备的更多信息?您似乎必须指定DIGCF_ALLCLASSES标志以查找与给定设备实例ID匹配的所有类,或者指定ClassGuid并使用DIGCF_DEFAULT标志.这对我有用:带输出:

  5. Windows Live ID是OpenID提供商吗?

    不,WindowsLiveID不是OpenID提供商.他们使用专有协议.自从他们的“测试版”期结束以来,他们从未宣布计划继续它.

  6. 如果我在代码中进行了更改,是否需要重新安装Windows服务?

    我写了一个Windows服务并安装它.现在我对代码进行了一些更改并重新构建了解决方案.我还应该重新安装服务吗?不,只需停止它,替换文件,然后重新启动它.

  7. 带有双引号的字符串回显使用Windows批处理输出文件

    我正在尝试使用Windows批处理文件重写配置文件.我循环遍历文件的行并查找我想要用指定的新行替换的行.我有一个’函数’将行写入文件问题是%Text%是一个嵌入双引号的字符串.然后失败了.可能还有其他角色也会导致失败.如何才能使用配置文件中的所有文本?尝试将所有“在文本中替换为^”.^是转义字符,因此“将被视为常规字符你可以尝试以下方法:其他可能导致错误的字符是:

  8. .net – 将控制台应用程序转换为服务?

    我正在寻找不同的优势/劣势,将我们长期使用的控制台应用程序转换为Windows服务.我们为ActiveMQ使用了一个叫做java服务包装器的东西,我相信人们告诉我你可以用它包装任何东西.这并不是说你应该用它包装任何东西;我们遇到了这个问题.控制台应用程序是一个.NET控制台应用程序,默认情况下会将大量信息记录到控制台,尽管这是可配置的.任何推荐?我们应该在VisualStudio中将其重建为服务吗?我使用“-install”/“-uninstall”开关执行此操作.例如,seehere.

  9. windows – 捕获外部程序的STDOUT和STDERR *同时*它正在执行(Ruby)

    哦,我在Windows上:-(实际上,它比我想象的要简单,这看起来很完美:…是的,它适用于Windows!

  10. windows – 当我试图批量打印变量时,为什么我得到“Echo is on”

    我想要执行一个简单的批处理文件脚本:当我在XP中运行时,它给了我预期的输出,但是当我在Vista或Windows7中运行它时,我在尝试打印值时得到“EchoisOn”.以下是程序的输出:摆脱集合表达式中的空格.等号(=)的两侧可以并且应该没有空格BTW:我通常在@echo关闭的情况下启动所有批处理文件,并以@echo结束它们,所以我可以避免将代码与批处理文件的输出混合.它只是使您的批处理文件输出更好,更清洁.

返回
顶部