说到protobuf,肯定会提到其高效、大厂开发有保障。

公司的项目用的都是protobuf 2,在军棋Demo项目中使用了protobuf3(C#版,感兴趣的大佬可以移步https://github.com/imzhangshirong/Violet-Kriegspiel)。

当时我问Leader,为什么我们不用最新的呢?回答是:目前没有比较好的支持protobuf3的Lua版本。哈哈,我当时还不信,去github搜了一波,有几个备选的方案(可以去github上搜一下,这里我就不介绍了~),但是都是大佬自己写的解析,对官方特性不是全都支持,于是我也就暂时放弃了。

直到最近,稍微有点空学习,当然也是为了Phantom做准备,心想着Unity都用上2018了,protobuf也该升级了,于是开启了这一段折腾…大致体验如下:

在经历各种开源库依赖问题、交叉编译报错和Unity崩溃后,终于,我tm还是搞出来了。你以为我要出教程了?!不不不,具体步骤整理起来太麻烦了(也不知道怎么整理),这里就记录一下解决思路和遇到的一些主要问题吧!

一开始我尝试进行基于protobuf2解释器的修改,显然对于我的能力是不可能的了,这需要对Lua以及protobuf源码接口的深入了解,短期内做不到,遂放弃。

开始考虑做现有官方库编程语言之间的转换,说到和Lua比较接近的语言,第一个想到的是js,js里Object和Lua里的table在语法和使用上太像了,js的原型链和Lua的元表也有共性。对于这次尝试,这个想法绝对是重要的,不仅可以保持protobuf和官方最新,也可以保证算法和代码的稳定性。在万能的Github上找到了一个项目castl可以将js库转为Lua版本,经过测试可用果断star和follow。

成功转换为Lua后,用lua执行,还是有几个地方出问题了。在castl中,没有对Uint8Array的支持,由于castl使用lua模块rex_pcre,需要安装;还有个问题是在Unity跑的时候出现的:toLua用的虚拟机不支持_ENV用法,所以对castl代码和protoc生成的文件做修改,也需要复写require方法支持(table,string)的传参。(具体的代码看各位大佬们的操作了~我就提个思路)

接下来提一下相关解决的方案,关于Uint8Array支持有能力的大佬可以自己用js按标准实现,当然还有个方案:使用Uint8Array的Polyfill版本js的typedarray库。对!把它也用castl转成Lua,啊哈哈真TM机智。

关于rex_pcre模块,由于在Unity里是基于toLua做的,所以需要在toLua_runtime里打包lrexlib里的pcre。有几点要注意,打包需要在对应环境下进行(比如win32和win64需要在Windows上打包)并且把lrexlib相关文件添加到gcc编译命令参数中。其次是编译lrexlib的时候是需要pcre库的,所以要先对pcre进行编译得到link文件。

关于pcre库的编译这里说一下:Windows下使用CMake_GUI生成cmake的配置,注意在Advance中将C++FLAGS和CFLAGS传入对应参数(32位就是-m32,64位是-m64,不然你只能编译出当前系统的版本),cmake配置好之后用mingw32-make进行编译得到如下文件:

将这些文件复制到MinGW的include和对应lib和lib32中,这样pcre库就算配置好了(其他平台配置起来更快,这里就不多说了,自行百度)。

接下来将生成的tolua.dll放到LuaFramework框架下的对应位置,跑Unity。这里有几个地方要注意:首先如果rex_pcre添加成功的话用dll查看器可以看到有luaopen_rex_pcre函数的,如下

在LuaFramwork中要注册这个库,并开启,具体代码请参考socket库开启的代码,这里不赘述了。(在测试与修改lrexlib代码过程中,不知道Unity奔溃了多少次了TAT)

接下来要解决的问题就是前面提到的_ENV特性支持的问题了。

终于,成功把官方js版Protobuf3移植到LuaFramework中了。具体代码文件和工具将同步在Phantom项目中。

总结下吧,还是那句话

Stsnding on Shoulders of Giants.

在整个过程中,学习和了解了相关依赖的代码,不禁感叹其复杂与精妙,这座“大厦”的一砖一瓦都有价值去学习,同时也弥补了自身的一些技术债和认知。

哈哈哈哈,是不是需要奖励下自己!比如过个没有情人的七夕:-D

===============================================分割线===============================================

8.22补充:

Android和Win的在Windows上都打包成功了,在Mac上打包MacOS和IOS的遇到了问题,主要是MacOS的,需要去xcode里只编译x86_64(注意,要编译macjit的,不然goto特性无法实现,nojit的是用的5.1lua的)编译libluajit.a文件需要通过make XCFLAGS=-DLUAJIT_ENABLE_GC64编译,否则xcode生成的tolua.bundle在Unity直接闪退。

之前漏了个CFLAG -DHAVE_CONFIG_H。

发表评论

电子邮件地址不会被公开。 必填项已用*标注