UE4 使用第三方lib、dll、.so、.a

发布时间 2023-05-23 20:07:02作者: tomato-haha

以下是在4.22.3版本中使用結果,版本不同可能會有所差異。

 

首先對於所有第三方庫都應該先加入對頭文件目錄的包含:

在模塊的Build.cs文件中,加入對應的第三方庫的頭文件包含路徑,這樣就可以在包含頭文件時,找到對應的文件;

 

PublicIncludePaths.Add(path);//包含目錄中的頭文件並公開到外部模塊

PrivateIncludePaths.Add(Path);//包含目錄中的頭文件並不公開到外部模塊,外部模塊訪問不到頭文件

例如:

PublicIncludePaths.Add("$(ModuleDir)/include")

對於插件中的模塊:

PublicIncludePathsPrivateIncludePaths可以接受特殊字符串開頭的字符串:

可接受以下特殊字符串有

$(ModuleDir) 表示模塊目錄(D:\UE4_Project\testSlate\Plugins\MotionMocap\Source\MotionMocap)

$(PluginDir) 表示插件目錄D:\UE4_Project\testSlate\Plugins\MotionMocap

$(EngineDir) 表示引擎目錄D:\Program Files (x86)\UE4\UE_4.22\Engine

$(ProjectDir) 表示工程目錄D:\UE4_Project\testSlate

不可接受的

$(TargetOutputDir)

$(BinaryOutputDir)

 

通常用法如下:PublicIncludePaths.Add("$(ModuleDir)/include")

如果path是相對路徑,則是從D:\Program Files (x86)\UE4\UE_4.22\Engine\Source,開始的相對路徑

對於非插件中的模塊:

PublicIncludePathsPrivateIncludePaths不接受特殊字符串

如果path是相對路徑,則是從工程目錄的Source開始D:\UE4_Project\testSlate\Source\,開始的相對路徑

 

接下來是庫文件的使用:

使用第三方lib和.a文件(也就是當使用靜態庫時)

首先要包含庫的搜索路徑(不是必須,爲了方便查找庫文件)

PublicLibraryPaths.Add(path)

例如:PublicLibraryPaths.Add("$(ModuleDir)/lib")

path對於插件和非插件模塊的規則與上面PublicIncludePaths.Add(path)一致

然後包含要使用的庫:

PublicAdditionalLibraries.Add(path)

例如:PublicAdditionalLibraries.Add("freetype26MT.lib")

path對於插件和非插件模塊的規則與上面PublicIncludePaths.Add(path)一致,需要帶文件後綴名

用法通常如下:

PublicAdditionalLibraries.Add("freetype26MT.lib");

PublicAdditionalLibraries.Add(FreeType2LibPath + "Mac/libfreetype2412.a");

PublicAdditionalLibraries.Add("arcore_sdk_c");//對於.a和.so, 沒有路徑時可以省略文件lib開通和後綴名,比如這裏的庫文件名可能是libarcore_sdk_c.so 或者libarcore_sdk_c.a

使用第三方dll

隱式連接方式:

首先要包含第三方lib文件的搜索路徑(不是必須,爲了方便查找庫文件)跟上面使用第三方lib文件一致

PublicLibraryPaths.Add(path)

PublicAdditionalLibraries.Add(path)

例如:

PublicLibraryPaths.Add("$(ModuleDir)/lib")

PublicAdditionalLibraries.Add("freetype26MT.lib")

 

然後需要將第三方dll文件放置到指定目錄中:

在插件中使用第三方庫時

放置在插件目錄的生成目錄中,比如:

在插件MotionMocap中時,放置在如下目錄中:

D:\UE4_Project\testSlate\Plugins\MotionMocap\Binaries\Win64

在遊戲項目中使用第三方庫時:

放置在項目的生成目錄中,比如:

D:\UE4_Project\testSlate\Binaries\Win64

這時,運行編輯器是沒有問題的,但如果打包的話,會出現dll文件沒有被打進包裏的情況。

所以需要使用以下設置:

 

RuntimeDependencies.Add(path,[SourcePath])

例如:RuntimeDependencies.Add("$(BinaryOutputDir)/libzmq-v141-mt-4_3_3.dll")

該設置會在打包項目時,將對應的目錄下的文件拷貝到打包項目對應目錄下。

對於隱式連接第三方dll來說,path都應該以$(BinaryOutputDir)開頭,然後跟上dll文件名稱和後綴。$(BinaryOutputDir)代表了插件或者遊戲生成二進制文件的目錄,也就是上面提到的D:\UE4_Project\testSlate\Plugins\MotionMocap\Binaries\Win64或者D:\UE4_Project\testSlate\Binaries\Win64,

 

當我們使用帶有SourcePath版本的RuntimeDependencies.Add時, 我們可以不用手動放置第三方dll文件到上面提到D:\UE4_Project\testSlate\Plugins\MotionMocap\Binaries\Win64或者D:\UE4_Project\testSlate\Binaries\Win64中,當我們編譯工程時,工程自動會複製SourcePath所指定的文件到path所指定的目錄。

 

例如:RuntimeDependencies.Add("$(BinaryOutputDir)/libzmq-v141-mt-4_3_3.dll", Path.Combine(ModuleDirectory, "ZeroMQ", "lib")+"\\" +"libzmq-v141-mt-4_3_3.dll");

 

當然RuntimeDependencies 並不僅限於dll,也可以用於其他文件的操作,但path路徑必須是以工程路徑開始的,比如工程路徑爲D:\UE4_Project\testSlate\,則path必須是D:\UE4_Project\testSlate\包含的目錄下的文件

path和sourcepath可接受以下特殊字符串

$(ModuleDir) 表示模塊目錄(D:\UE4_Project\testSlate\Plugins\MotionMocap\Source\MotionMocap)

$(PluginDir) 表示插件目錄,僅在插件模塊中有效,遊戲模塊會報錯D:\UE4_Project\testSlate\Plugins\MotionMocap

$(EngineDir) 表示引擎目錄D:\Program Files (x86)\UE4\UE_4.22\Engine

$(ProjectDir) 表示工程目錄D:\UE4_Project\testSlate

$(TargetOutputDir)表示Directory containing the output executable,也就是exe文件輸出目錄,這個好像只在打包時有效。

$(BinaryOutputDir)表示Directory containing the binary that links this module.也就是dll文件目錄

 

顯式連接方式:

因爲不需要lib文件,所有我們只需要設置

RuntimeDependencies.Add(path,[SourcePath])

這裏path並不需要設置爲$(BinaryOutputDir)開頭的形式,只需設置爲以工程路徑開始即可,具體使用方法可以看這裏:

https://wiki.unrealengine.com/Linking_Dlls

 

使用第三方.SO文件

首先要包含第三方.so文件的搜索路徑(不是必須,爲了方便查找庫文件)

PublicLibraryPaths.Add(path)

 

例如:PublicLibraryPaths.Add("$(ModuleDir)/lib/android/arm7/")

然後包含要使用的庫:

 

PublicAdditionalLibraries.Add(path)

例如:PublicAdditionalLibraries.Add("libcef.so")

 

然後對於Android和linux有不同的策略:

Android:

string BuildPath = Utils.MakePathRelativeTo(ModuleDirectory, BuildConfiguration.RelativeEnginePath);

AdditionalPropertiesForReceipt.Add(new ReceiptProperty("AndroidPlugin", Path.Combine(BuildPath, "My_APL_armv7.xml")));

 

My_APL_armv7.xml文件放到與build.cs同目錄下

內容如下:

<?xml version="1.0" encoding="utf-8"?>

<!-- steps to add to build additions -->

<root xmlns:android="http://schemas.android.com/apk/res/android">

<!-- init section is always evaluated once per architecture -->

<init>

<setBool result="bSupported" value="false"/>

<isArch arch="armeabi-v7a">

<setBool result="bSupported" value="true"/>

</isArch>

</init>

 

<!-- optional files or directories to copy to Intermediate/Android/APK -->

<resourceCopies>

<isArch arch="armeabi-v7a">

<copyFile src="$S(PluginDir)/armv7/libcrypto.so"

dst="$S(BuildDir)/libs/armeabi-v7a/libcrypto.so" />

</isArch>

</resourceCopies>

 

<!-- optional libraries to load in GameActivity.java before libUE4.so -->

<soLoadLibrary>

<if condition="bSupported">

<true>

<loadLibrary name="myso" failmsg="Failed to load myso library" />

</true>

</if>

</soLoadLibrary>

</root>

更具體的請看這裏:

https://wiki.unrealengine.com/index.php?title=How_to_add_a_shared_library_(.so)_in_android_project

Linux:

需要設置.so文件使用依賴,以便打包時複製到打包項目對應目錄

RuntimeDependencies.Add(path,[SourcePath])

例如:RuntimeDependencies.Add("$(ProjectDir)/lib/libopenvr_api.so");

這裏path並不需要設置爲$(BinaryOutputDir)開頭的形式,只需設置爲以工程路徑開始即可。

然後設置運行時庫的搜索路徑:

PrivateRuntimeLibraryPaths.Add(path);

 

這裏的路徑path應該是上面RuntimeDependencies.Add(path)path的目錄:例如:PrivateRuntimeLibraryPaths.Add("$(ProjectDir)/lib/");