為什么要添加lua-pb模塊?
Unity項(xiàng)目中需要使用protocol buffer作為網(wǎng)絡(luò)通信的序列化格式。uLua本身包含了一些protobuf的處理模塊,比如sproto,pblua等等。但是實(shí)測(cè)下來發(fā)現(xiàn)這些預(yù)置的模塊或多或少都有些嚴(yán)重的缺陷,比較嚴(yán)重的有如下幾條:
- 有的模塊不支持default關(guān)鍵字
- 有的模塊解析proto之后會(huì)生成一個(gè)lua文件,但是如果proto文件很長(zhǎng),生成出來的lua文件會(huì)由于local變量太多而解析出錯(cuò)。
這些問題導(dǎo)致現(xiàn)有的模塊不能滿足項(xiàng)目開發(fā)的需求,只能尋求第三方的解決方案。
lua-pb模塊是一個(gè)開源的protobuf的lua解析模塊,功能比較齊全。于是決定把lua-pb模塊集成到uLua中,替換掉ulua本身的解析模塊。
修改ulua
下載uLua
uLua的源碼可以從https://github.com/jarjin/ulua_runtime_project這個(gè)git倉(cāng)庫(kù)里clone到。
下載struct
lua-pb依賴三個(gè)lua的擴(kuò)展庫(kù),lpeg,luabitop和struct,前兩個(gè)已經(jīng)包含在了ulua中,只需添加struct支持即可。
struct是lua的一個(gè)c擴(kuò)展庫(kù),為lua提供了c struct的支持。
struct的下載地址是http://www.inf.puc-rio.br/~roberto/struct/。
修改uLua工程
不同平臺(tái)下需要分別編譯ulua,至少需要編譯windows,mac,ios和android平臺(tái)的版本。uLua的源碼倉(cāng)庫(kù)內(nèi)有每個(gè)平臺(tái)工程的詳細(xì)文檔,需要按照文檔操作。
windows,mac,ios和android使用了不同的工程和編譯工具鏈來編譯,所以需要分別添加struct到對(duì)應(yīng)的工程中。
下面截圖是mac平臺(tái)的例子,其它的工程類似。
編譯
mac版本使用xcode編譯,編譯出來的是一個(gè)bundle。將這個(gè)bundle替換工程中的Plugins目錄下原來的uLua.bundle就可以了。
ios版本一樣使用xcode編譯,編譯出來的是一個(gè)靜態(tài)庫(kù),靜態(tài)庫(kù)中需要包含armv7和arm64兩個(gè)CPU架構(gòu)。使用編譯出來的靜態(tài)庫(kù)替換掉Plugins/iOS目錄下原來的libulua.a文件就可以了。
android版本使用ndk編譯,需要編譯v7a和x86兩個(gè)版本,編譯出來的是個(gè).so的動(dòng)態(tài)庫(kù)。替換掉Plugins/Android/libs對(duì)應(yīng)目錄下的舊文件就可以了。
windows版本在msys環(huán)境下編譯,msys的下載地址參照ulua編譯文檔里的說明。需要編譯x86和x64兩個(gè)版本,替換掉Plugins目錄下對(duì)應(yīng)的ulua.dll就可以了。
修改uLua的C#源碼
LuaDLL.cs:112的LuaDLL類中添加
[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int luaopen_struct(IntPtr L);
LuaScriptMgr.cs:213中LuaScriptMgr的構(gòu)造函數(shù)中添加
LuaDLL.luaopen_struct(lua.L);
使用lua-pb
假如有如下的message定義在proto文件中
package Protocol;
message LOGIN_RESULT()
{
optional int32 cmd_id = 1 [default = 100];
required int32 result = 2;
}
可以按照如下測(cè)試代碼在lua中處理消息的序列化和反序列化。序列化之后的字節(jié)流一般通過socket發(fā)送給服務(wù)器。
funciton ProtoTest()
-- 序列化
local sendMsg = Protocol.LOGIN_RESULT()
sendMsg.result = 100
local bytes = sendMsg:Serialize()
-- 反序列化
local recvMsg = Protocol.LOGIN_RESULT()
recvMsg:Parse(bytes)
print("received result" ... recvMsg.result)
end
總結(jié)
在ulua中,添加第三方的lua的c語言擴(kuò)展庫(kù)是比較簡(jiǎn)單的,感謝ulua的開發(fā)者的工作。
添加lua-pb需要改寫ulua的源代碼,更改之后的ulua源代碼也一并上傳到了github上,地址是https://github.com/cooado/ulua_runtime_project,有需要可以直接參考源碼工程。
補(bǔ)充說明
uLua一直在更新,目前推薦的版本是toLua#。本文的內(nèi)容可能不直接適用,但是原理是類似的。
(全文完)