xlua擴充套件第三方庫記錄
隨著xlua的開源,其在專案中的使用也越來越廣泛。遊戲開發中我們經常會使用第三方庫如,json解析,網路協議等等,目前xlua目前內建的擴充套件庫:
1、針對luajit的64位整數支援;
2、函式呼叫耗時以及記憶體洩漏定位工具;
3、用於支援ZeroBraneStudio的luasocket庫;
4、tdr 4 lua;
隨著使用專案的增加以及專案使用的深入程度,僅有這幾個擴充套件已經沒法滿足專案組了,而由於各個專案對擴充套件差異化比較大,以及手機平臺對安裝包大小的敏感,XLua是無法通過預整合去滿足這些需求,結合官網的例程記錄下自己擴充套件的步驟以及遇到的錯誤
我的環境大概如下:
windows作業系統,
xlua最新原始碼(版本105),
vs2015,cmake(3.13),
第三方擴充套件原始碼(提前下載好rapidjson)
步驟
1、安裝cmake(根據自己電腦配置選擇合適的版本)
cmake安裝之後最好重啟下電腦,即便環境變數已經配置好,但是有時還是會不識別
根據例子修改CMakeLists.txt檔案,接入擴充套件
把xLua的C原始碼包解壓到你Unity工程的Assets同級目錄下。
2、在CMakeLists.txt加入擴充套件
下載lua-rapidjson程式碼,按你的習慣放置。本教程是把rapidjson標頭檔案放到$UnityProj\build\lua-rapidjson\include目錄下,
而擴充套件的原始碼rapidjson.cpp放到$UnityProj\build\lua-rapidjson\source目錄下(注:$UnityProj指的是你工程的目錄)
xLua的各平臺Plugins編譯使用cmake編譯,好處是所有平臺的編譯都寫在一個makefile,大部分編譯處理邏輯是跨平臺的。
xLua配套的CMakeLists.txt為第三方擴充套件提供了擴充套件點(都是list):
THIRDPART_INC:第三方擴充套件的標頭檔案搜尋路徑。
THIRDPART_SRC:第三方擴充套件的原始碼。
THIRDPART_LIB:第三方擴充套件依賴的庫。
如下是rapidjson的加
#begin lua-rapidjson
set (RAPIDJSON_SRC lua-rapidjson/source/rapidjson.cpp)
set_property(
SOURCE ${RAPIDJSON_SRC}
APPEND
PROPERTY COMPILE_DEFINITIONS
LUA_LIB
)
list(APPEND THIRDPART_INC lua-rapidjson/include)
set (THIRDPART_SRC ${THIRDPART_SRC} ${RAPIDJSON_SRC})
#end lua-rapidjson
3、修改執行bat檔案
比如windows 64位lua53版本是make_win64_lua53.bat,android的luajit版本是make_android_luajit.sh,要編譯哪個版本就執行相應的指令碼即可。
執行完編譯指令碼會自動拷貝到plugin_lua53或者plugin_luajit目錄,前者是lua53版本放置路徑,後者是luajit。
配套的android指令碼是在linux下使用的,指令碼開頭的NDK路徑要根據實際情況修改。雙擊執行結果如下圖:
然後把生成的plugin_lua53/Plugins/x86_64/xlua.dll 直接覆蓋unity專案的Assets/Plugins/x86_64/xlua.dll
4、c#整合
所有lua的C擴充套件庫都會提供個luaopen_xxx的函式,xxx是動態庫的名字,比如lua-rapidjson庫該函式是luaopen_rapidjson,這類函式由lua虛擬機器在載入動態庫時自動呼叫,而在手機平臺,由於ios的限制我們載入不了動態庫,而是直接編譯進程序裡頭。
為此,XLua提供了一個API來替代這功能(LuaEnv的成員方法):
public void AddBuildin(string name, LuaCSFunction initer)
name:buildin模組的名字,require時輸入的引數;
initer:初始化函式,原型是這樣的public delegate int lua_CSFunction(IntPtr L),必須是靜態函式,而且帶MonoPInvokeCallbackAttribute屬性修飾,這個api會檢查這兩個條件。
我們以luaopen_rapidjson的呼叫來看看怎麼使用。
擴充套件LuaDLL.Lua類,用pinvoke把luaopen_rapidjson匯出到C#,然後寫一個符合lua_CSFunction定義的靜態函式,你可以在裡頭做寫初始化工作,比如luaopen_rapidjson的呼叫,以下是完整程式碼:
namespace LuaDLL
{
public partial class Lua
{
[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int luaopen_rapidjson(System.IntPtr L);
[MonoPInvokeCallback(typeof(LuaDLL.lua_CSFunction))]
public static int LoadRapidJson(System.IntPtr L)
{
return luaopen_rapidjson(L);
}
}
}
然後在lua虛擬機器建立時呼叫AddBuildin:
luaenv.AddBuildin("rapidjson", LuaDLL.Lua.LoadRapidJson);
例子測試程式碼
local rapidjson = require('rapidjson')
local t = rapidjson.decode('{"a":123}')
print(t.a)
t.a = 456
local s = rapidjson.encode(t)
print('json', s)
當以上步驟都完成時重啟unity報錯了,報錯資訊如下:
這是因為我下載的xlua版本是104的,生成的xlua.dll是105版本的,去官網下載最新的xlua原始碼替換下就好了