找回密码
 立即注册
查看: 227|回复: 0

unity-tolua集成pb3支持

[复制链接]
发表于 2023-4-9 11:08 | 显示全部楼层 |阅读模式

title: unity-tolua集成pb3支持
categories: Unity3d
tags: [unity, pb3, tolua]
date: 2021-11-18 10:45:39
comments: false
mathjax: true
toc: true


unity-tolua集成pb3支持

前篇

    tolua_runtime 编译 - https://zhuanlan.zhihu.com/p/81935911tolua中使用protobuf3—集成lua-protobuftolua#各个平台添加自定义扩展并编译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-protobuftolua_runtime - https://github.com/topameng/tolua_runtime
  • tolua编译集成lua-protobuf指南 (好文) - https://john.js.org/2020/11/02/ToLua-Compile-With-lua-protobuf/
      https://github.com/jozhn/tolua_runtime_pb

源码修改

    把 lua-protobuf 的 pb.c 和 pb.h 文件复制到 tolua_runtime 文件夹中
  • pb.c 中 luaL_newlib 为 lua5.2 版本才支持的语法,而 tolua 是 5.1,所以找到以下几个函数进行如下修改,判断 Lua 版本进行不同的调用:
    1. LUALIB_API intluaopen_pb_io(lua_State *L){//...luaL_register(L,"pb.io", libs);luaL_newlib(L, libs);return1;}
    2. LUALIB_API intluaopen_pb_conv(lua_State *L){//...luaL_register(L,"pb.io", libs);luaL_newlib(L, libs);return1;}
    3. LUALIB_API intluaopen_pb(lua_State *L){//...luaL_register(L,"pb", libs);luaL_newlib(L, libs);return1;}
    复制代码

平台编译

Windows


  • 32位编译
    进入 msys2文件夹,打开mingw32.exe。cd 进入到 tolua 代码所在的文件夹(我的在D盘):
    1. $ cd d:
    2. $ cd WorkSpace/tolua_runtime
    3. $ ./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. publicclassLuaDLL{publicstaticstring version ="1.0.7.386";// 加入 [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]publicstaticexternintluaopen_pb(IntPtr L);[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]publicstaticexternintluaopen_pb_io(IntPtr L);[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]publicstaticexternintluaopen_pb_conv(IntPtr L);[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]publicstaticexternintluaopen_pb_buffer(IntPtr L);[DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]publicstaticexternintluaopen_pb_slice(IntPtr L);...}
    复制代码
  • LuaClient 中注册 pb 全局变量
    1. publicclassLuaClient{protectedvirtualvoidOpenLibs(){// lua-protobuf
    2.         luaState.OpenLibs(LuaDLL.luaopen_pb);
    3.         luaState.OpenLibs(LuaDLL.luaopen_pb_io);
    4.         luaState.OpenLibs(LuaDLL.luaopen_pb_conv);
    5.         luaState.OpenLibs(LuaDLL.luaopen_pb_buffer);
    6.         luaState.OpenLibs(LuaDLL.luaopen_pb_slice);}}
    复制代码
    然后就可以在 lua 中直接使用 pb 全局变量, 不需要 require
    1. -- local pb = require "pb"local newData = pb.decode("csproto.Person", bytes)
    复制代码

lua 中 require 注册

    在 lua 中 require 注册
    1. local pb = require "pb"local newData = pb.decode("csproto.Person", bytes)
    复制代码
      因为在 lua 中 require 一个 xxx 库时, 会调用动态库的 c 函数: luaopen_xxx, 里面会完成 pb 的全局变量注册
      1. LUALIB_API intluaopen_pb(lua_State *L){...#ifLUA_VERSION_NUM <502luaL_register(L,"pb", libs);#elseluaL_newlib(L, libs);#endifreturn1;}
      复制代码


lua 中使用
  1. localfunctiontestPb3Decode()gLog("--- testPb3Decode")local pb     = require "pb"-- load stringlocal protoc = require "3rd.lua-protobuf.protoc"-- protoc 是 https://github.com/starwing/lua-protobuf 提供的工具
  2.     protoc.include_imports =trueassert(protoc:load [[
  3.         syntax = "proto3";
  4.         package csproto;
  5.         enum Color {
  6.             Red = 1;
  7.             Green = 2;
  8.             Blue = 3;
  9.         }
  10.         message Phone {
  11.             string name = 1;
  12.             int64 phonenumber = 2;
  13.         }
  14.         
  15.         message Person {
  16.             string name = 1;
  17.             int32 age = 2;
  18.             string address = 3;
  19.             repeated Phone contacts = 4;
  20.         }
  21.         ]])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, numbergLog("--- pb enum, em02: {0}, type: {1}", em02,type(em02))--> "Green", string-- lua 表数据local data ={
  22.         name ="ilse",
  23.         age  =18,
  24.         address ="zhongguo",
  25.         contacts ={{ name ="alice", phonenumber =12312341234},{ name ="bob",   phonenumber =45645674567}},
  26.         act01 ={
  27.             Speed =666,
  28.             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.htmltolua_runtime 配置mingw - https://github.com/topameng/tolua_runtime/wikimsys2安装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. $ pacman -S mingw-w64-i686-gcc
      2. $ pacman -S mingw-w64-x86_64-gcc
      3. $ pacman -S mingw-w64-i686-make
      4. $ pacman -S mingw-w64-x86_64-make
      5. $ pacman -S make
      复制代码
        如果提示什么PGP签名失效,那么需要更新已知密钥:
        1. $ pacman-key --refresh-keys
        复制代码


  • done. 然后就可以去编译 tolua_runtime
    比如编译 x86_64, 启动 mingw64.exe
    1. $ cd /e/workspace/cpp/lua-pb3/tolua_runtime/
    2. $ ./build_win64.sh
    复制代码
    编译成功后就会出现在 tolua_runtime\window\x86_64 目录下

修改导表工具

    可以参考我这篇文章: go-excel转protobuf

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-14 07:28 , Processed in 0.110268 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表