當 Unity 需要使用第三方的庫的時候,特別是第三方開發(fā)庫是使用 C/C++ 來實現(xiàn)的時候,我們就需要針對各個平臺編譯 Library 來供 Unity 使用。
最近剛剛有過一次封裝經(jīng)驗,放在此供大家參考。
這里分三部分來介紹。
Unity 端函數(shù)聲明
#if UNITY_STANDALONE_WIN || UNITY_EDITOR
public const string PluginName = "liblz4";
#else
#if UNITY_IOS || UNITY_XBOX360
// On iOS and Xbox 360 plugins are statically linked into
// the executable, so we have to use __Internal as the
// library name
public const string PluginName = "__Internal";
#else
// Other platforms load plugins dynamically, so pass the name
// of the plugin's dynamic library.
public const string PluginName = "lz4";
#endif
#endif
[DllImport(PluginName)]
static extern YOUR_RETURN_TYPE YOUR_FUNCTION_NAME(YOUR_PARAMETRES);
注意點:
- Standalone 平臺, PluginName 就是動態(tài)庫或者Bundle的名字;
- IOS 平臺一般使用源文件就好,直接用 __Internal;
- Android 平臺 PluginName 中不能有 lib 字段,導出的 so 中需要有 lib 字段,例如 liblz4.so。
封裝代碼
一般是一個頭文件加上一個實現(xiàn)文件,頭文件中聲明函數(shù),實現(xiàn)文件中實現(xiàn)函數(shù)。
函數(shù)聲明格式
#ifdef _WIN32
#ifdef XXX_EXPORT
#define EXPORT_API __declspec(dllexport)
#else
#define EXPORT_API __declspec(dllimport)
#endif
#else
#define EXPORT_API
#endif
extern "C" {
EXPORT_API YOUR_RETURN_TYPE YOUR_FUNCTION_NAME(YOUR_PARAMETERS);
}
注意只有在 Windows 上需要在工程中設置 XXX_EXPORT 預處理變量。
C++ 對象參數(shù)怎么表示
在C#層使用 IntPtr 表示,在 C++ 層使用對象指針表示。
例如 Class A 作為函數(shù)參數(shù):
// C++
EXPORT_API void Func(A* pA);
// C#
[DllImport(PluginName)]
static extern void Func(IntPtr a);
數(shù)組怎么傳遞
數(shù)組傳遞類似于對象傳遞,使用指針和一個數(shù)組長度字段表示即可。
List/Array 等對象怎么傳遞
轉(zhuǎn)換成數(shù)組
平臺庫封裝
Windows
Windows 使用 VisualStudio 來創(chuàng)建一個 Visual C++ 類庫工程來編譯,如下圖所示。

image.png
然后注意導出的平臺是 x86/x64 即可,注意需要在工程預處理器中聲明
XXX_EXPORT, vs 提示缺少 stdafx.h 的時候設置配置屬性->C/C++->預編譯頭為不使用預編譯頭即可。
Mac
Mac 平臺需要創(chuàng)建一個 Xcode Bundle 工程,如下圖所示。

image.png

image.png
iOS
直接將 .c/.mm 放入工程就好,最為簡單。
Android
需要下載 Android SDK 和 Android NDK, 使用 Android Studio 創(chuàng)建一個 Include C++ Support 的工程,然后將我們的 C/C++ 代碼加入到工程中。最后使用 Android NDK 編譯成 .so。

image.png
庫文件存放位置
- Windows 放在
Plugins/x86(x64)目錄下; - Mac 直接放在
Plugins目錄下; - iOS 放在
Plugins/iOS目錄下; - Android 放在
Plugins/Android/libs/armeabi-v7a目錄下。
注意點
- 如果修改了本地插件,需要將 dll 或者 bundle 覆蓋了之后重啟 Unity, 不然還是會使用老的 Native Plugin;
- 調(diào)試起來比較麻煩,建議使用文件的方式進行日志輸出來進行比較。