xlua - 增加protobuf庫

yanghui01發表於2024-03-07

lua下常用的2個protobuf庫

1) GitHub - starwing/lua-protobuf: A Lua module to work with Google protobuf

2) GitHub - cloudwu/pbc: A protocol buffers library for C

這邊使用第1個庫

a) 下載lua-protobuf原始碼,並解壓到xlua的build資料夾根目錄

b) CMakeLists.txt中加入以下配置

#begin lua-profobuf
set (LPB_SRC "lua-protobuf-master/pb.c")
set_property(
        SOURCE ${LPB_SRC}
        APPEND
        PROPERTY COMPILE_DEFINITIONS
        LUA_LIB
)
list(APPEND THIRDPART_INC lua-protobuf)
set(THIRDPART_SRC ${THIRDPART_SRC} ${LPB_SRC})
#end lua-protobuf

c) 這邊要編譯Window下的lua5.3的x64版本的dll,所以執行make_win64_lua53.bat

d) 將新生成的xlua.dll替換Unity中的(如果Unity已開啟,需要重啟下,才能載入新的dll)

e) 測試是否成功

新建MyLua.cs,用於放dll載入程式碼

namespace XLua.LuaDLL
{

    public partial class Lua
    {
        [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
        public static extern int luaopen_pb(System.IntPtr L);

        [MonoPInvokeCallback(typeof(LuaDLL.lua_CSFunction))]
        public static int LoadPb(System.IntPtr L)
        {
            return luaopen_pb(L);
        }
    }

}

新建Lua指令碼,Lua/Test8.lua.txt

local pb = require("pb")
local serpent = require("Scenes.serpent")

local protoBytes = Test8MonoInst:LoadProtoFile()
pb.load(protoBytes)

local data = {
    name = "Alice",
    id = 12345,
    phone = {
        { number = "1301234567" },
        { number = "87654321", type = "WORK" },
    }
}

local data2 = pb.encode("demo.Person", data)
local data3 = pb.decode("demo.Person", data2)
print(serpent.block(data3))

新建測試指令碼Test8.cs

using System.Text;
using UnityEditor;
using UnityEngine;
using XLua;

public class Test8 : MonoBehaviour
{
    private LuaEnv m_LuaEnv;

    void Start()
    {
        m_LuaEnv = new LuaEnv();
        m_LuaEnv.AddLoader((ref string filePath) =>
        {
            Debug.Log($"custom loader:{filePath}");
            filePath = filePath.Replace('.', '/');
            filePath = $"Assets/{filePath}.lua.txt";
            var txtAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(filePath);
            return Encoding.UTF8.GetBytes(txtAsset.text);
        });

        m_LuaEnv.AddBuildin("pb", XLua.LuaDLL.Lua.LoadPb);
        m_LuaEnv.Global.Set("Test8MonoInst", this);
        m_LuaEnv.DoString("require('Lua.Test8')");
    }

    void OnDestroy()
    {
        if (null != m_LuaEnv)
            m_LuaEnv.Dispose();
    }

    public byte[] LoadProtoFile()
    {
        var txtAsset = AssetDatabase.LoadAssetAtPath<TextAsset>($"Assets/proto.bytes"); //不要用.bytes.txt這樣的字尾, 會按錯誤的Encoding去當做文字讀的
        if (null != txtAsset)
        {
            byte[] bytes = txtAsset.bytes;
            if (null == bytes)
                bytes = Encoding.UTF8.GetBytes(txtAsset.text);
            return bytes;
        }
        return null;
    }

}

f) 涉及的proto檔案:Src/AddressBook.proto

syntax = "proto2";
package demo;

option java_package = "com.demo";
option java_outer_classname = "AddressBook";

message Person {
  required string name = 1;
  required int32 id = 2;        // Unique ID number for this person.
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
  repeated int32 test = 5 [packed=true];

  extensions 10 to max; 
}

message Ext {
  extend Person {
    optional int32 test = 10;
  }
}

// Our address book file is just one of these.
message AddressBook {
  repeated Person person = 1;
}

下載proto工具:Releases · protocolbuffers/protobuf (github.com)

proto檔案生成二進位制檔案bat

protoGen.bat

@ECHO OFF
CHCP 65001

ECHO start
protoc -o "./proto.bytes" "./Src/*.proto"
ECHO finsh
ECHO=

PAUSE

g)

參考

lua-protobuf 使用說明 - 知乎 (zhihu.com)

[遊戲開發][unity]Xlua中使用proto、json、lpeg_xlua cjson-CSDN部落格

build_xlua_with_libs/build at master · chexiongsheng/build_xlua_with_libs · GitHub

[RS] xLua從LuaJit升級Lua5.3記錄 - 簡書 (jianshu.com)

相關文章