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

tolua集成lua-protobuf库

[复制链接]
发表于 2021-8-12 09:59 | 显示全部楼层 |阅读模式
在tolua基础上,为了方便使用proto3,这里集成了lua-protobuf库!
十分感谢两位开源库的大大,tolua的蒙大和lua-protobuf的Xavier!在两位的github上有q群的联系方式,欢迎加群交流!
有什么问题也可以在我blog下留言!
本文基于win7x64,unity2017.4,tolua当前最新版本,tolua_runtime当前最新版本,lua-protobuf当前最新版本编写
一丶编译tolua库
资源下载:
tolua_runtime
https://github.com/topameng/tolua_runtime
NDK 版本:android-ndk-r10e 默认安装到 D:/android-ndk-r10e
https://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip
配置好的Msys2下载
https://pan.baidu.com/s/1c2JzvDQ
lua-protobuf
https://github.com/starwing/lua-protobuf
正文:
1.将lua-protobuf工程中的pb.c和pb.h拷贝到tolua_runtime根目录,覆盖pb.c
编译各平台dll
https://www.jianshu.com/p/5a35602adef8?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
2.编译后tolua_runtime下的Plugins文件夹拷贝至tolua文件夹下同名覆盖
问题:
1.NDK路径问题
在tolua_runtime中
build_arm.sh
build_arm64.sh
build_x86.sh
link_arm64.bat
中ndk路径需要和你电脑上ndk的目录一致!
2.群友的总结
(感谢 lua-protobuf交流群 - 潜水的小懒猫 么么哒!)
a.在mac上替换tolua.bundle文件时,需要重启unity,不然无法读取pb
b.在编译mac时,会提示i386架构被弃用,需删掉,将不再支持iPhone5以下机型
(如果执行build_osx.sh时提示不在支持32位,请打开macnojit 在build Setting移除i386的支持即可)
c.在发布ios时,要删除tolua目录下的pb.c文件,不然编译不通过
d.如果执行.sh提示权限不足 可以在终端执行:chmod 777 tolua根目录 然后再次执行.sh脚本即可
3.编译工具的一些说明
Msys2下载后,在其根目录有mingw32_shell.bat和mingw64_shell.bat用来分别开启32位和64位 Msys
32位用于执行tolua_runtime中的build_arm.sh、build_win32.sh、build_x86.sh
64位用于执行tolua_runtime中的build_arm64.sh、build_win64.sh
build_ios.sh、build_osx.sh需要在mac 下执行
build_ubuntu.sh需要在linux下执行(不使用linux开发,不要要编译)
4…sh怎么执行?
在各终端(PC用Msys,mac和linux都是自带)进入.sh脚本所在目录 ./xxx.sh


5.各种.sh执行中的Error
一定要注意,有错误就要修改,要不打出的dll不保证好用!Error的种类有很多,可以参见出错时的日志,大部分都是配置的问题,要是C库有问题,及时联系对应库的作者,验证是否为bug!
二丶tolua接入(编写测试Demo)
资源下载:
tolua
https://github.com/topameng/tolua
正文:
1.将lua-protobuf中的protoc.lua、luaunit.lua和serpent.lua拷贝至tolua工程Assets\ToLua\Lua(tolua自带lua)文件夹下或者Assets\Lua(自己的业务lua)下
2.unity打开tolua工程,在LuaDLL.cs public static extern int luaopen_pb(IntPtr L);这行下添加
  1.                 // lua-protobuf >>>>>>>
  2.         [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
  3.         public static extern int luaopen_pb_io(IntPtr L);
  4.         [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
  5.         public static extern int luaopen_pb_conv(IntPtr L);
  6.         [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
  7.         public static extern int luaopen_pb_buffer(IntPtr L);
  8.         [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
  9.         public static extern int luaopen_pb_slice(IntPtr L);
  10.         // lua-protobuf <<<<<<
复制代码
3.在Assets\ToLua\Examples\TestLuaProtobuf新建测试目录,在该目录下新建测试场景TestLuaProtobuf,新建测试脚本TestLuaProtobuf.cs挂于MainCamera下
TestLuaProtobuf.cs脚本如下
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using LuaInterface;
  6. using System;
  7. public class TestLuaProtobuf : MonoBehaviour {
  8.     //lua-protobuf 测试用lua脚本
  9.     string script =
  10.         @"
  11.             local pb = require 'pb'
  12.             local protoc = require 'protoc'
  13.             -- load schema from text
  14.             assert(protoc:load[[
  15.                message Phone {
  16.                     optional string name = 1;
  17.                     optional int64  phonenumber = 2;
  18.                 }
  19.                 message Person
  20.                 {
  21.                     optional string name = 1;
  22.                 optional int32  age      = 2;
  23.                   optional string address = 3;
  24.                 repeated Phone  contacts = 4;
  25.                } ]])
  26.             -- lua table data
  27.             local data = {
  28.                name = 'ilse',
  29.                age  = 18,
  30.                contacts = {
  31.                   { name = 'alice', phonenumber = 12312341234 },
  32.                   { name = 'bob',   phonenumber = 45645674567 }
  33.                }
  34.             }
  35.             -- encode lua table data into binary format in lua string and return
  36.             local bytes = assert(pb.encode('Person', data))
  37.             print(pb.tohex(bytes))
  38.             -- and decode the binary data back into lua table
  39.             local data2 = assert(pb.decode('Person', bytes))
  40.             print(require 'serpent'.block(data2))
  41.         ";
  42.     int bundleCount = int.MaxValue;
  43.     string tips = null;
  44.     LuaState luaState = null;
  45.     bool testAB = false;//是否打包AB加载
  46.     void Start()
  47.     {
  48. #if UNITY_5 || UNITY_2017 || UNITY_2018
  49.         Application.logMessageReceived += ShowTips;
  50. #else
  51.         Application.RegisterLogCallback(ShowTips);
  52. #endif
  53.         if (!testAB)
  54.         {
  55.             OnBundleLoad();
  56.             return;
  57.         }
  58.         LuaFileUtils file = new LuaFileUtils();
  59.         file.beZip = true;
  60. #if UNITY_ANDROID && UNITY_EDITOR
  61.         if (IntPtr.Size == 8)
  62.         {
  63.             throw new Exception("can't run this in unity5.x process for 64 bits, switch to pc platform, or run it in android mobile");
  64.         }
  65. #endif
  66.         StartCoroutine(LoadBundles());
  67.     }
  68.     void OnBundleLoad()
  69.     {
  70.         luaState = new LuaState();
  71.         luaState.Start();
  72.         OpenLuaProtobuf();
  73.         luaState.DoString(script);
  74.         luaState.Dispose();
  75.         luaState = null;
  76.     }
  77.     /// <summary>
  78.     /// 这里tolua在OpenLibs的时候并不一定会注册,这里注册一下
  79.     /// </summary>
  80.     void OpenLuaProtobuf()
  81.     {
  82.         luaState.LuaGetField(LuaIndexes.LUA_REGISTRYINDEX, "_LOADED");
  83.         luaState.OpenLibs(LuaDLL.luaopen_pb);
  84.         luaState.LuaSetField(-2, "pb");
  85.         luaState.OpenLibs(LuaDLL.luaopen_pb_io);
  86.         luaState.LuaSetField(-2, "pb.io");
  87.         luaState.OpenLibs(LuaDLL.luaopen_pb_conv);
  88.         luaState.LuaSetField(-2, "pb.conv");
  89.         luaState.OpenLibs(LuaDLL.luaopen_pb_buffer);
  90.         luaState.LuaSetField(-2, "pb.buffer");
  91.         luaState.OpenLibs(LuaDLL.luaopen_pb_slice);
  92.         luaState.LuaSetField(-2, "pb.slice");
  93.     }
  94.     void ShowTips(string msg, string stackTrace, LogType type)
  95.     {
  96.         tips += msg;
  97.         tips += "\r\n";
  98.     }
  99.     void OnGUI()
  100.     {
  101.         GUI.Label(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 150, 400, 300), tips);
  102.     }
  103.     void OnApplicationQuit()
  104.     {
  105. #if UNITY_5 || UNITY_2017 || UNITY_2018
  106.         Application.logMessageReceived -= ShowTips;
  107. #else
  108.         Application.RegisterLogCallback(null);
  109. #endif
  110.     }
  111.     IEnumerator CoLoadBundle(string name, string path)
  112.     {
  113.         using (WWW www = new WWW(path))
  114.         {
  115.             if (www == null)
  116.             {
  117.                 Debugger.LogError(name + " bundle not exists");
  118.                 yield break;
  119.             }
  120.             yield return www;
  121.             if (www.error != null)
  122.             {
  123.                 Debugger.LogError(string.Format("Read {0} failed: {1}", path, www.error));
  124.                 yield break;
  125.             }
  126.             --bundleCount;
  127.             LuaFileUtils.Instance.AddSearchBundle(name, www.assetBundle);
  128.             www.Dispose();
  129.         }
  130.     }
  131.     IEnumerator LoadFinished()
  132.     {
  133.         while (bundleCount > 0)
  134.         {
  135.             yield return null;
  136.         }
  137.         OnBundleLoad();
  138.     }
  139.     public IEnumerator LoadBundles()
  140.     {
  141.         string streamingPath = Application.streamingAssetsPath.Replace('\\', '/');
  142. #if UNITY_5 || UNITY_2017 || UNITY_2018
  143. #if UNITY_ANDROID && !UNITY_EDITOR
  144.         string main = streamingPath + "/" + LuaConst.osDir + "/" + LuaConst.osDir;
  145. #else
  146.         string main = "file:///" + streamingPath + "/" + LuaConst.osDir + "/" + LuaConst.osDir;
  147. #endif
  148.         WWW www = new WWW(main);
  149.         yield return www;
  150.         AssetBundleManifest manifest = (AssetBundleManifest)www.assetBundle.LoadAsset("AssetBundleManifest");
  151.         List<string> list = new List<string>(manifest.GetAllAssetBundles());
  152. #else
  153.         //此处应该配表获取
  154.         List<string> list = new List<string>() { "lua.unity3d", "lua_cjson.unity3d", "lua_system.unity3d", "lua_unityengine.unity3d", "lua_protobuf.unity3d", "lua_misc.unity3d", "lua_socket.unity3d", "lua_system_reflection.unity3d" };
  155. #endif
  156.         bundleCount = list.Count;
  157.         for (int i = 0; i < list.Count; i++)
  158.         {
  159.             string str = list[i];
  160. #if UNITY_ANDROID && !UNITY_EDITOR
  161.             string path = streamingPath + "/" + LuaConst.osDir + "/" + str;
  162. #else
  163.             string path = "file:///" + streamingPath + "/" + LuaConst.osDir + "/" + str;
  164. #endif
  165.             string name = Path.GetFileNameWithoutExtension(str);
  166.             StartCoroutine(CoLoadBundle(name, path));
  167.         }
  168.         yield return StartCoroutine(LoadFinished());
  169.     }
  170. }
复制代码
4.各平台测试
pc上
TestLuaProtobuf.cs 脚本中testAB = false,直接运行测试场景TestLuaProtobuf即可,正常输出


移动端
TestLuaProtobuf.cs 脚本中testAB = true
unity切换至对应平台,例如切换至Android,执行untiy菜单栏 Lua/Build bundle files no jit,等待打包执行完毕,分别在Assets\StreamingAssets下生成对应平台lua AB包,Android、iOS



添加测试场景,build 安装包即可!
安卓正常结果


问题:
1.关于集成时tolua使用lua-lua-protobuf时的注册问题,两位大佬的issues对答
https://github.com/topameng/tolua/issues/168

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

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

本版积分规则

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

GMT+8, 2024-11-24 07:06 , Processed in 0.097978 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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