UE4.27推出了一项新的机制,可以把UE编译成库,能够嵌入到外部程序中,由其他的程序来驱动引擎的执行与消息通信。但是目前官方还没有放出任何有价值的文档,我分析了引擎中的相关代码,提出一个UE as Lib的实践方案,理论上也能在4.27之前的引擎版本实现,或许会与后续官方发布的文档不一致,权当抛砖引玉。相关的研究内容也会在本篇文章中持续更新。
首先,我认为UE as Lib并不是以静态链接库的方式提供的,因为引擎内具有大量依赖UHT和UBT的代码,而且还具有大量的模板实现,想要编译出一个独立的Lib是非常麻烦的,并且使用时还需要抽取大量的代码,所以我认为UE as Lib是将引擎编译成DLL的形式提供的,外部程序通过DLL的导出符号驱动引擎。
注意:目前UE as Lib只能用于Windows平台。
UE在4.27中加入了一个新的Runtime Module:UELibrary,用于导出外部驱动引擎的符号。
其导出的符号为:
1 | extern "C" |
提供了四个到处函数用于初始化引擎、Tick、传递消息、关闭引擎,符合前面的推断,将引擎编译成DLL,外部程序通过调用这四个函数来实现驱动引擎。
关于如何编译UE as Lib,我提供一个思路。首先要明确需求:
- 将引擎编译成一个独立的DLL
- 依赖UELibrary模块的导出符号
- 必须通过UE的编译系统来编译引擎
为了实现这几个需求,需要了解UE的构建系统。
注意:UE的UE as Lib也可以将游戏项目编译为DLL,由外部程序来驱动引擎启动游戏,只需要将下面的操作从Program换到游戏项目的Target即可。
UE的Module,需要被Target依赖才能够通过UE的构建系统进行编译。之前我写过一篇文章,可以将UE作为一个库来实现console或WinGUI程序:Create A Standalone Application in UE4,在这篇文章中我提供了一个开源工具ue4program,可以方便地创建一个StandaloneApplication程序,由Program依赖UELibrary模块,然后编译这个Program,将UELibrary模块和依赖的Module编译其中。
然后,Pogram默认是编译成exe的,想要实现UE as Lib编译成DLL,其实就是将Program的Target编译成DLL!
首先需要通过hxhb/ue4program创建一个Standalone Application模板:
1 | # ue4program.exe ProgramName |
将创建出的目录放到引擎的Source/Programs
下,执行GenerateProjectFiles.bat
刷新sln,即可在UE4.sln中看到创建的Program项目。
将UELibrary
模块添加至UEProgram
的依赖:
1 | PrivateDependencyModuleNames.Add("UELibrary"); |
然后编辑UEProgram
的Target.cs
,需要修改LinkType:
1 | LinkType = TargetLinkType.Monolithic; |
这样会把所有的代码都编译到一个最终的二进制中,UE默认的则是Modular
,通过DLL方式访问其他的模块。
还需要修改bShouldCompileAsDLL
:
1 | // Whether this target should be compiled as a DLL. Requires LinkType to be set to TargetLinkType.Monolithic. |
默认为false,会把Program编译成一个exe,但是我们的目标就是DLL。
添加UE_LIBRARY_ENABLED=1
宏,在UELibrary中只有这个宏为1,才包含了前面导出符号的实现代码:
1 | GlobalDefinitions.Add("UE_LIBRARY_ENABLED=1"); |
修改之后编译UEProgram这个项目即可,编译完成之后即可在引擎的Binaries/Win64
下看到UProgram.dll
。
它包含了引擎代码、以及UELibrary的导出符号,可以在外部程序中通过OpenLibrary
来加载和执行,就是常规的C++调用动态链接库的用法了。编译出DLL之后,就实现了UE as Lib,使用方就可以脱离UE的编译系统,在普通的程序中调用了。
简单总结一下,目前UE as lib其实并不是一个完全全新的东西,只是UE把驱动引擎的API做了符号导出,在4.27之前的引擎版本中,也可以通过实现一个UELibrary的模块导出符号,通过文中的这种方式实现引擎的动态链接库化。
时间问题,暂时只分析到这里,至于编译出的DLL如何嵌入第三方程序由外部来驱动引擎,有时间再来补充。
相关链接: