unity-tolua集成pb3支持
unity-tolua集成pb3支持
前篇
- tolua_runtime 编译 - https://zhuanlan.zhihu.com/p/81935911
- tolua中使用protobuf3—集成lua-protobuf
- tolua#各个平台添加自定义扩展并编译tolua库 - https://www.codeleading.com/article/99421036965/
- tolua中使用protobuf3—集成lua-protobuf
使用了 lua-protobuf, 那么 protoc-gen-lua 将不能使用.
lua-protobuf 使用的是 protoc 3.x 版本去生成 proto 语义文件
网上流行导表工具 xls_deploy_tool.py 也不能使用, 因为这个使用的 python 2.x, protoc 2.x 版本去生成的
但是只要修改一下这个工具即可 修改导表工具, 使用 python 3.x, protoc 3.x 去生成 数据二进制 和 proto 语义二进制.
这样项目就可以完全丢弃 python 2.x, protoc 2.x
集成到 tolua 框架中
- lua-protobuf - https://github.com/starwing/lua-protobuf
- tolua_runtime - https://github.com/topameng/tolua_runtime
- tolua编译集成lua-protobuf指南 (好文) - https://john.js.org/2020/11/02/ToLua-Compile-With-lua-protobuf/
源码修改
把 lua-protobuf 的
pb.c
和pb.h
文件复制到tolua_runtime
文件夹中pb.c
中luaL_newlib
为 lua5.2 版本才支持的语法,而 tolua 是 5.1,所以找到以下几个函数进行如下修改,判断 Lua 版本进行不同的调用:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23LUALIB_API int luaopen_pb_io(lua_State *L)
{
//...
luaL_register(L, "pb.io", libs);
luaL_newlib(L, libs);
return 1;
}
LUALIB_API int luaopen_pb_conv(lua_State *L)
{
//...
luaL_register(L, "pb.io", libs);
luaL_newlib(L, libs);
return 1;
}
LUALIB_API int luaopen_pb(lua_State *L)
{
//...
luaL_register(L, "pb", libs);
luaL_newlib(L, libs);
return 1;
}
平台编译
Windows
32位编译
进入 msys2文件夹,打开mingw32.exe。cd 进入到 tolua 代码所在的文件夹(我的在D盘):
1
2
3$ cd d:
$ cd WorkSpace/tolua_runtime
$ ./build_win32.sh然后在
Plugins\x86
目录下看见tolua.dll
文件便编译成功64位编译
跟上面一样,只不过是打开mingw64.exe执行相同操作,执行的脚本改成:
1
$ ./build_win64.sh
然后在
Plugins\x86_64
目录下看见tolua.dll
文件便编译成功
Android
- 要先准备NDK10环境 https://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip
下载完成后解压到不包含中文和空格的目录下 - 将 build_arm.sh , build_x86.sh , build_arm64.sh .文件中的 NDK 路径改为自己本地存储的路径
- 我的是D:/android-ndk-r10e
- 将 link_arm64.bat 文件中的 ndkPath 修改为上面的NDK解压路径下。只需要修改上面文件中的根路径。不要修改 NDK 的版本
android平台用得最多的cpu架构体系是Acorn公司的arm和Intel公司x86,由于arm市场占有率最高,大多android的app也就只编译了arm版本,所以Intel也专门针对arm体系架构做了一个转换程序,也就是说,arm程序在x86机子上也可以跑起来。所以,一般来说,只要编译arm就可以了(最常用的CPU和ABI是ARMv7a),当然,将x86也编译起来是极好的,据以往分析闪退的经验,在x86机子上闪退的一大元凶就是那个转换程序出了问题,代价就是会增加包体的大小(每多支持一个CPU架构,就是多编译一个动态库so)。
注意:经过测试,NDK版本必须是 android-ndk-r10e
才可以编译,更新的版本生成文件的位置不一样,编译脚本会失效。
armeabi-v7a
- 提前需要保证当前目录下存在
Plugins\Android\libs\armeabi-v7a
目录,不然没有文件输出 - 在
msys2
的32位编译环境中执行./build_arm.sh
. - 然后在
Plugins\Android\libs\armeabi-v7a
目录下看见libtolua.so
文件便编译成功
- 提前需要保证当前目录下存在
arm64-v8a
- 提前需要保证当前目录下存在
Plugins\Android\libs\arm64-v8a
目录,不然没有文件输出 - 在
msys2
的64位编译环境中执行./build_arm64.sh
. - 然后在
Plugins\Android\libs\arm64-v8a
目录下看见libtolua.so
文件便编译成功
- 提前需要保证当前目录下存在
iOS
必须在Mac机器上编译
环境:macOS Mojav 10.14.5,Xcode 9.4.1
arm64 : 必选项,支持iphone5s及以上;最低支持版本:iOS5.1.1
armv7s:支持iPhone5及以上
armv7:支持iPhone4及以上
我把 build_ios.sh
中的armv7和armv7s那段指令删除了,没必要支持那么低的iPhone版本。
- 打开终端.切换到
tolua_runtime
目录下 - 在终端中运行
build_ios.sh
.如果遇见权限不足,用chmod +x
命令提升权限 - 然后在
Plugins\iOS
目录下看见libtolua.a
文件便编译成功
Mac
必须在Mac机器上编译
- 打开终端.切换到
tolua_runtime
目录下 - 在终端中运行
build_osx.sh
.如果遇见权限不足,用chmod +x
命令提升权限 - 然后在
Plugins
目录下看见tolua.bundle
库文件便编译成功
lua-protobuf 注册
有几种方式
csharp 中注册 pb 全局变量 (建议)
在
LuaDLL.cs
中增加几个 pb 注册函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class LuaDLL
{
public static string version = "1.0.7.386";
// 加入
[ ]
public static extern int luaopen_pb(IntPtr L);
[ ]
public static extern int luaopen_pb_io(IntPtr L);
[ ]
public static extern int luaopen_pb_conv(IntPtr L);
[ ]
public static extern int luaopen_pb_buffer(IntPtr L);
[ ]
public static extern int luaopen_pb_slice(IntPtr L);
...
}在 LuaClient 中注册 pb 全局变量
1
2
3
4
5
6
7
8
9
10
11
12public class LuaClient
{
protected virtual void OpenLibs()
{
// lua-protobuf
luaState.OpenLibs(LuaDLL.luaopen_pb);
luaState.OpenLibs(LuaDLL.luaopen_pb_io);
luaState.OpenLibs(LuaDLL.luaopen_pb_conv);
luaState.OpenLibs(LuaDLL.luaopen_pb_buffer);
luaState.OpenLibs(LuaDLL.luaopen_pb_slice);
}
}然后就可以在 lua 中直接使用 pb 全局变量, 不需要 require
1
2
3
4
5
6
7
8
9
10
11
12
13
14-- local pb = require "pb"
local newData = pb.decode("csproto.Person", bytes)
---
##### lua 中 require 注册
1. 在 lua 中 require 注册
```lua
local pb = require "pb"
local newData = pb.decode("csproto.Person", bytes)因为在 lua 中 require 一个
xxx
库时, 会调用动态库的 c 函数:luaopen_xxx
, 里面会完成pb
的全局变量注册1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75LUALIB_API int luaopen_pb(lua_State *L) {
...
luaL_register(L, "pb", libs);
luaL_newlib(L, libs);
return 1;
}
---
##
```lua
local function testPb3Decode()
gLog("--- testPb3Decode")
local pb = require "pb"
-- load string
local protoc = require "3rd.lua-protobuf.protoc" -- protoc 是 https://github.com/starwing/lua-protobuf 提供的工具
protoc.include_imports = true
assert(protoc:load [[
syntax = "proto3";
package csproto;
enum Color {
Red = 1;
Green = 2;
Blue = 3;
}
message Phone {
string name = 1;
int64 phonenumber = 2;
}
message Person {
string name = 1;
int32 age = 2;
string address = 3;
repeated Phone contacts = 4;
}
]])
local em01 = pb.enum("csproto.Color", "Blue")
local em02 = pb.enum("csproto.Color", 1)
gLog("--- pb enum, em01: {0}, type: {1}", em01, type(em01)) --> 2, number
gLog("--- pb enum, em02: {0}, type: {1}", em02, type(em02)) --> "Green", string
-- lua 表数据
local data = {
name = "ilse",
age = 18,
address = "zhongguo",
contacts = {
{ name = "alice", phonenumber = 12312341234 },
{ name = "bob", phonenumber = 45645674567 }
},
act01 = {
Speed = 666,
Msg = "nice~",
},
}
-- 将Lua表编码为二进制数据
local bytes = pb.encode("csproto.Person", data)
-- 再解码回Lua表
local newData = pb.decode("csproto.Person", bytes)
dump(newData, "--- newData")
gLog("--- num: {0}", type(newData.contacts[1].phonenumber))
end
windows 平台编译环境 - msys2
- win10系统64位安装msys2最新版 - https://www.cnblogs.com/CodeWorkerLiMing/p/12274583.html
- tolua_runtime 配置mingw - https://github.com/topameng/tolua_runtime/wiki
- msys2安装gcc、g++编译器 - https://blog.csdn.net/Lazybones_3/article/details/88633738
配置源.
MSYS2 镜像使用帮助 - https://mirrors.tuna.tsinghua.edu.cn/help/msys2/ , 使用清华源速度会快点
安装软件包
启动 msys2.exe, 输入命令
1
$ pacman --needed -Sy bash pacman pacman-mirrors msys2-runtime
安装好运行环境之后要把 msys2 的控制台关掉,进到 msys2 的文件夹中运行
autorebase.bat
为什么要这样做?因为如果不rebase的话 msys2 就没法更新其他软件包,这是 msys2 的问题。
启动 msys2.exe, 先更新软件包数据库和系统包:
1
$ pacman -Syu
安装需要的组件
1
2
3
4
5$ pacman -S mingw-w64-i686-gcc
$ pacman -S mingw-w64-x86_64-gcc
$ pacman -S mingw-w64-i686-make
$ pacman -S mingw-w64-x86_64-make
$ pacman -S make如果提示什么PGP签名失效,那么需要更新已知密钥:
1
$ pacman-key --refresh-keys
done. 然后就可以去编译 tolua_runtime
比如编译 x86_64, 启动 mingw64.exe
1
2$ cd /e/workspace/cpp/lua-pb3/tolua_runtime/
$ ./build_win64.sh编译成功后就会出现在
tolua_runtime\window\x86_64
目录下
修改导表工具
- 可以参考我这篇文章: go-excel转protobuf