tolua_runtime 集成 lua-protobuf 第三方pb3解析库
编译环境
- 源码
- 源码下载: 从 https://github.com/topameng/tolua_runtime 下载源码
- lua-protobuf: https://github.com/starwing/lua-protobuf 下载源码
- 工具(windows)
- 配置好的环境(建议): msys2
- 自己配置环境(不建议): wiki
准备工作
- 命令行下跳转到
msys2
的目录下:如 c:\msys2 目录cd c:\msys2
- 执行
mingw32_shell.bat
启动32位编译环境,只能编译32位的库 - 执行
mingw64_shell.bat
启动64位编译环境,只能编译64位的库
32位环境和64位环境不能交叉编译.
- (主要步骤)将
lua-protobuf
中的两个文件解析文件替换到tolua_runtime
库中 - 将
pb.c
中的luaopen_pb
函数替换为
LUALIB_API int luaopen_pb(lua_State *L) {
luaL_Reg libs[] = {
{ "pack", Lbuf_pack },
{ "unpack", Lslice_unpack },
#define ENTRY(name) { #name, Lpb_##name }
ENTRY(clear),
ENTRY(load),
ENTRY(loadfile),
ENTRY(encode),
ENTRY(decode),
ENTRY(types),
ENTRY(fields),
ENTRY(type),
ENTRY(field),
ENTRY(typefmt),
ENTRY(enum),
ENTRY(defaults),
ENTRY(hook),
ENTRY(tohex),
ENTRY(result),
ENTRY(option),
ENTRY(state),
#undef ENTRY
{ NULL, NULL }
};
luaL_Reg meta[] = {
{ "__gc", Lpb_delete },
{ "setdefault", Lpb_state },
{ NULL, NULL }
};
if (luaL_newmetatable(L, PB_STATE)) {
luaL_setfuncs(L, meta, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
}
#if LUA_VERSION_NUM < 502
luaL_register(L, "pb", libs);
#else
luaL_newlib(L, libs);
#endif
return 1;
}
编译库
windows库
32位
- 提前需要保证当前目录下存在
Plugins\x86
目录,不然没有文件输出 - 在
msys2
的32位编译环境中执行./build_win32.sh
. - 然后在
Plugins\x86
目录下看见tolua.dll
文件便编译成功
64位
- 提前需要保证当前目录下存在
Plugins\x86_64
目录,不然没有文件输出 - 在
msys2
的64位编译环境中执行./build_win64.sh
. - 然后在
Plugins\x86_64
目录下看见tolua.dll
文件便编译成功
Android库
准备环境
- 编译前需要下载NDK NDK下载地址
- 下载完成后解压到不包含中文和空格的目录下
- 将
build_arm.sh
,build_x86.sh
,build_arm64.sh
.文件中的NDK
路径改为自己本地存储的路径 - 将
link_arm64.bat
文件中的ndkPath
修改为上面的NDK解压路径下 只需要修改上面文件中的根路径.不要修改NDK
的版本 - 注意:需要用android-ndk-r13b的NDK编译,如果用android-ndk-r16b则不能成功
armeabi-v7a
- 提前需要保证当前目录下存在
Plugins\Android\libs\armeabi-v7a
目录,不然没有文件输出 - 在
msys2
的32位编译环境中执行./build_arm.sh
. - 然后在
Plugins\Android\libs\armeabi-v7a
目录下看见libtolua.so
文件便编译成功
x86
- 提前需要保证当前目录下存在
Plugins\Android\libs\x86
目录,不然没有文件输出 - 在
msys2
的32位编译环境中执行./build_x86.sh
. - 然后在
Plugins\Android\libs\x86
目录下看见libtolua.so
文件便编译成功
arm64-v8a
- 提前需要保证当前目录下存在
Plugins\Android\libs\arm64-v8a
目录,不然没有文件输出 - 在
msys2
的64位编译环境中执行./build_arm64.sh
. - 然后在
Plugins\Android\libs\arm64-v8a
目录下看见libtolua.so
文件便编译成功
iOS
- 将
tolua_runtime
工程git clone https://github.com/topameng/tolua_runtime.git
到MAC - 打开终端.切换到
tolua_runtime
目录下 - 在终端中运行
build_ios.sh
.如果遇见权限不足,用chmod +x命令提升权限 - 然后在
Plugins\iOS
目录下看见libtolua.a
文件便编译成功
MAC
- 将
tolua_runtime
工程git clone https://github.com/topameng/tolua_runtime.git
到MAC - 打开终端.切换到
tolua_runtime
目录下 - 在终端中运行
build_osx.sh
.如果遇见权限不足,用chmod +x命令提升权限 - 然后在
Plugins
目录下看见tolua.bundle
库文件便编译成功
编译完成
- 在 Unity工程中的
LuaDLL.cs
中找到luaopen_pb
函数位置 - 将代码替换为
/*
** third party library
*/
[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int luaopen_pb(IntPtr L);
[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int luaopen_pb_io(IntPtr L);
[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int luaopen_pb_conv(IntPtr L);
[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int luaopen_pb_buffer(IntPtr L);
[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int luaopen_pb_slice(IntPtr L);
- 找到
LuaClient.cs
或者你自己修改后的类文件中找到OpenLibs
函数 - 在函数的最前端加上,注意,不要删除原来的
m_LuaState.OpenLibs(LuaDLL.luaopen_pb);
// m_LuaState 为 LuaState 对象
m_LuaState.OpenLibs(LuaDLL.luaopen_pb_io);
m_LuaState.OpenLibs(LuaDLL.luaopen_pb_conv);
m_LuaState.OpenLibs(LuaDLL.luaopen_pb_buffer);
m_LuaState.OpenLibs(LuaDLL.luaopen_pb_slice);
- 将对应的编译出来的库文件替换到Unity 工程中
集成验证(在移动平台上测试)
将
test.lua
中的代码复制一份出来测试
local pb = require "pb"
local protoc = require "tolua/3rd/lua-protobuf/protoc" -- pb路径。不要替换之前库中的pbc
-- load schema from text
assert(protoc:load [[
syntax = "proto3";
message Phone {
string name = 1;
int64 phonenumber = 2;
}
message Person {
string name = 1;
int32 age = 2;
string address = 3;
repeated Phone contacts = 4;
} ]])
-- lua table data
local data = {
name = "ilse",
age = 18,
contacts = {
{ name = "alice", phonenumber = 12312341234 },
{ name = "bob", phonenumber = 45645674567 }
}
}
-- encode lua table data into binary format in lua string and return
--- 这里如果要解析 byte[] 数组, 需要将 buffer 转换为C# 中的 LuaByteBuffer 类型
-- local bytes = assert(pb.encode("Person", buffer))
local bytes = assert(pb.encode("Person", data))
print(pb.tohex(bytes))
-- and decode the binary data back into lua table
local data2 = assert(pb.decode("Person", bytes))
print(require "tolua/3rd/lua-protobuf/serpent".block(data2))
如果可以正常打印 16进制 和 table 格式化后的表,表示集成成功
参考文档
- https://github.com/NewbieGameCoder/tolua_runtime/wiki
- https://github.com/topameng/tolua_runtime/wiki
- http://changxianjie.com/tolua%E9%9B%86%E6%88%90lua-protobuf/
- https://www.jianshu.com/p/5a35602adef8
编辑于 2019-09-11 11:08