xLua下使用lua-protobuf

本文發表於程序員劉宇的博客,轉載請註明來源:http://www.javashuo.com/article/p-giauofyv-gm.htmlhtml

 

前言android

protobuf做爲一種通用套接字格式,各類插件裏,最本質、最關鍵的就是基於二進制的兩個操做:ios

1. 根據proto文件打包出二進制數據。c++

2. 根據二進制數據反串化出須要的數據格式。 git

因此其實在不一樣平臺下須要的就是各自的解析庫。做爲跨平臺的套接字,同版本二進制打包出來的格式必須徹底同樣,1裏的proto文件通常也是要在項目開發中多平臺通用,2裏反串化的格式是當前語言和環境下的格式。在lua環境裏,通常反串化出來的就是table。程序員

因爲官方並無給lua支持,因此你們各自發揮,使用的比較多的有4種:github

1. pbc-lua: 雲風早期寫的解析庫,解析官方protoc.exe生成的pb,缺點是隻解析一層。json

2. sproto: 雲風(真是孜孜不倦高產出)強推的第二版協議,其實已經不能徹底說是proto,而是一種新套接字,只是兼容。這是他本身關於sproto的說明: https://blog.codingnow.com/2015/04/sproto_rpc.htmlapi

3. protoc-gen-lua: seanlin寫的插件,這個你們用的也多,ulua,tolua的不少項目都用這個。原理是生成lua端的.lua描述文件,打包時先使用描述文件的定義來New,而後Serialize。只支持到5.1,後面就沒有維護了。框架

4. lua-protobuf: 這個如今你們用的多,是目前在莉莉絲工做的starwing寫的,這個使用起來也很簡單,能夠讀pb,也能夠直接讀定義文件(性能捉急),而後直接在lua按照proto格式寫table,encode就好了。 

下面說說如何接入lua-protobuf插件,參考連接:

xLua官方:https://github.com/Tencent/xLua

xLua官方集成第三方庫:https://github.com/chexiongsheng/build_xlua_with_libs

lua-protobuf:https://github.com/starwing/lua-protobuf

 

編庫文件

1. 首先是要得到庫文件,先去集成的git下查看一下版本,有一些已經編號的是否能夠用,裏面是根據xlua的版原本保存了一些編好的庫,具體有ffi,lpeg,rapidjson,lua-protobuf,pbc(chexiongsheng大佬貼心)。


 

2. 沒有現成的版本也不要緊,咱們把相關的庫和xlua的源碼一塊兒編一下就好了。先拿下第三方庫的svn,再把咱們實際使用的那個版本的xlua源碼下下來(如:https://github.com/Tencent/xLua/tree/master/build),拷到本地下好的build_xlua_with_libs文件夾裏。而後根據平臺分別編譯.安卓下NDK,cmake,ninja,AndroidSDK,JDK通通安裝好,點擊make_android_lua53.bat,PC下的先安裝好cmake和c++的vs環境,點擊make_win64_lua53.bat,MAC下先"chmod 777 make_ios_lua53.sh",而後執行 "./make_ios_lua53.sh"。編完了之後plugin_lua53\Plugins下就有各平臺的庫文件啦。

 

 

把庫文件加入項目

1. 使用xLua提供的加載靜態庫方法AddBuildin,這個方法能夠指定在lua側指定特定庫文件名在C#端的加載方法,而且限定了格式: 

1 public void AddBuildin(string name, LuaCSFunction initer) 2  //name:buildin模塊的名字,require時輸入的參數; 3  //initer:初始化函數,原型是這樣的public delegate int lua_CSFunction(IntPtr L),必須是靜態函數, 4  //並且帶MonoPInvokeCallbackAttribute屬性修飾,這個api會檢查這兩個條件。

 2. 接着咱們在某個地方定義一下這個LuaCSFunction,通常是在LuaDLL.cs裏,這裏把luaopen_pb這個方法extern過來,寫進了LoadPb裏 

 1 namespace LuaDLL  2 {  3     public partial class Lua  4  {  5         [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]  6         public static extern int luaopen_pb(System.IntPtr L);  7 
 8         [MonoPInvokeCallback(typeof(LuaDLL.lua_CSFunction))]  9         public static int LoadPb(System.IntPtr L) 10  { 11             return luaopen_pb(L); 12  } 13  } 14 }

 3. 準備完畢後,在咱們lua端的初始化的地方添加加載這個"pb"庫的方法:

1 LuaEnv luaenv = new LuaEnv(); 2 luaenv.AddBuildin("pb", XLua.LuaDLL.Lua.LoadPb); 3 --luaenv.AddBuildin("rapidjson", XLua.LuaDLL.Lua.LoadRapidJson);

 4. 這樣的話在lua中再require 'pb'的時候就會自動調用pb庫

1 -- 加載pb文件
2 local pb = require "pb"

好了接下來就能夠寫網路框架代碼了。

 

框架代碼接入

1. 先加載proto結構定義,前面提到能夠加載pb或者proto.Schema結構,分別以下:

    第一種你們都熟悉,編一下pb文件,使用loadfile加載

1 -- 加載pb文件,須要把proto編成pb使用
2 local pb = require "pb"
3 assert(pb.loadfile "login.pb")

    第二種是我使用的,由於是Schema結構,作成文本文件方便結合資源系統更新

1 local pb = require "pb"
2 local protoc = require "protoc" --protoc在lua-protobuf的目錄裏 
3 
4 local protoString = ResLoader.Instance:LoadLuaProtoFile('login.proto.txt') --用本身的資源系統加載文本格式文件
5 protoc:load(protoString) --加載文本文件的內容

 2. 使用pb解碼,編碼協議。這一步就是標準的流程了,lua-protobuf能夠直接對定義好的結構decode/encode:

 1 -- 定義表數據
 2 local loginCS = {  3     username="jack",  4     password="123456",  5 }  6 
 7 -- 序列化
 8 local bytes = assert(pb.encode("login.req_login", loginCS))  9 print(pb.tohex(bytes)) 10 
11 -- 反序列化
12 local recvData = assert(pb.decode("login.req_login", bytes)) 13 print(recvData .username)

 到這就跟之前其餘平臺使用protobuf沒有什麼區別了,這篇入門到此結束。

相關文章
相關標籤/搜索