Unity的uLua庫(kù)添加lua-pb實(shí)現(xiàn)網(wǎng)絡(luò)通信

為什么要添加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工程

編譯

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)容可能不直接適用,但是原理是類似的。


(全文完)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容