zoukankan      html  css  js  c++  java
  • xLua下使用lua-protobuf

    本文发表于程序员刘宇的博客,转载请注明来源:https://www.cnblogs.com/xiaohutu/p/12168781.html

    前言

    protobuf作为一种通用套接字格式,各种插件里,最本质、最关键的就是基于二进制的两个操作:

    1. 根据proto文件打包出二进制数据。

    2. 根据二进制数据反串化出需要的数据格式。 

    所以其实在不同平台下需要的就是各自的解析库。作为跨平台的套接字,同版本二进制打包出来的格式必须完全一样,1里的proto文件一般也是要在项目开发中多平台通用,2里反串化的格式是当前语言和环境下的格式。在lua环境里,一般反串化出来的就是table。

    由于官方并没有给lua支持,所以大家各自发挥,使用的比较多的有4种:

    1. pbc-lua: 云风早期写的解析库,解析官方protoc.exe生成的pb,缺点是只解析一层。

    2. sproto: 云风(真是孜孜不倦高产出)强推的第二版协议,其实已经不能完全说是proto,而是一种新套接字,只是兼容。这是他自己关于sproto的说明: https://blog.codingnow.com/2015/04/sproto_rpc.html

    3. protoc-gen-lua: seanlin写的插件,这个大家用的也多,ulua,tolua的很多项目都用这个。原理是生成lua端的.lua描述文件,打包时先使用描述文件的定义来New,然后Serialize。只支持到5.1,后面就没有维护了。

    4. lua-protobuf: 这个现在大家用的多,是目前在莉莉丝工作的starwing写的,这个使用起来也很简单,可以读pb,也可以直接读定义文件(性能捉急),然后直接在lua按照proto格式写table,encode就行了。 

    下面说说如何接入lua-protobuf插件,参考链接:

    xLua官方:https://github.com/Tencent/xLua

    xLua官方集成第三方库:https://github.com/chexiongsheng/build_xlua_with_libs

    lua-protobuf:https://github.com/starwing/lua-protobuf

    编库文件

    1. 首先是要获得库文件,先去集成的git下查看一下版本,有一些已经编号的是否可以用,里面是根据xlua的版本来保存了一些编好的库,具体有ffi,lpeg,rapidjson,lua-protobuf,pbc(chexiongsheng大佬贴心)。

    2. 没有现成的版本也没关系,我们把相关的库和xlua的源码一起编一下就行了。先拿下第三方库的svn,再把我们实际使用的那个版本的xlua源码下下来(如:https://github.com/Tencent/xLua/tree/master/build),拷到本地下好的build_xlua_with_libs文件夹里。然后根据平台分别编译.安卓下NDK,cmake,ninja,AndroidSDK,JDK统统安装好,点击make_android_lua53.bat,PC下的先安装好cmake和c++的vs环境,点击make_win64_lua53.bat,MAC下先"chmod 777 make_ios_lua53.sh",然后执行 "./make_ios_lua53.sh"。编完了以后plugin_lua53Plugins下就有各平台的库文件啦。

     

    把库文件加入项目

    1. 使用xLua提供的加载静态库方法AddBuildin,这个方法可以指定在lua侧指定特定库文件名在C#端的加载方法,并且限定了格式: 

    1 public void AddBuildin(string name, LuaCSFunction initer)
    2  //name:buildin模块的名字,require时输入的参数;
    3  //initer:初始化函数,原型是这样的public delegate int lua_CSFunction(IntPtr L),必须是静态函数,
    4  //而且带MonoPInvokeCallbackAttribute属性修饰,这个api会检查这两个条件。

     2. 接着我们在某个地方定义一下这个LuaCSFunction,一般是在LuaDLL.cs里,这里把luaopen_pb这个方法extern过来,写进了LoadPb里 

    复制代码
     1 namespace LuaDLL
     2 { 
     3     public partial class Lua
     4     {
     5         [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)]
     6         public static extern int luaopen_pb(System.IntPtr L);
     7 
     8         [MonoPInvokeCallback(typeof(LuaDLL.lua_CSFunction))]
     9         public static int LoadPb(System.IntPtr L)
    10         {    
    11             return luaopen_pb(L);  
    12         }
    13     }
    14 }
    复制代码

     3. 准备完毕后,在我们lua端的初始化的地方添加加载这个"pb"库的方法:

    1 LuaEnv luaenv = new LuaEnv();
    2 luaenv.AddBuildin("pb", XLua.LuaDLL.Lua.LoadPb);
    3 --luaenv.AddBuildin("rapidjson", XLua.LuaDLL.Lua.LoadRapidJson);

     4. 这样的话在lua中再require 'pb'的时候就会自动调用pb库

    1 -- 加载pb文件
    2 local pb = require "pb"

    好了接下来就可以写网路框架代码了。

    框架代码接入

    1. 先加载proto结构定义,前面提到可以加载pb或者proto.Schema结构,分别如下:

        第一种大家都熟悉,编一下pb文件,使用loadfile加载

    1 -- 加载pb文件,需要把proto编成pb使用
    2 local pb = require "pb"
    3 assert(pb.loadfile "login.pb")

        第二种是我使用的,因为是Schema结构,做成文本文件方便结合资源系统更新

    复制代码
    1 local pb = require "pb"
    2 local protoc = require "protoc" --protoc在lua-protobuf的目录里 
    3 
    4 local protoString = ResLoader.Instance:LoadLuaProtoFile('login.proto.txt') --用自己的资源系统加载文本格式文件
    5 protoc:load(protoString) --加载文本文件的内容
    复制代码

     2. 使用pb解码,编码协议。这一步就是标准的流程了,lua-protobuf可以直接对定义好的结构decode/encode:

    复制代码
     1 -- 定义表数据
     2 local loginCS = {
     3     username="jack",
     4     password="123456",
     5 }
     6 
     7 -- 序列化
     8 local bytes = assert(pb.encode("login.req_login", loginCS))
     9 print(pb.tohex(bytes))
    10 
    11 -- 反序列化
    12 local recvData = assert(pb.decode("login.req_login", bytes))
    13 print(recvData .username)
    复制代码

     到这就跟以前其他平台使用protobuf没有什么区别了,这篇入门到此结束。

     

  • 相关阅读:
    并发编程的艺术
    Redis字符串实现,SDS与C的区别,空间预分配
    Jvm
    Redis数据结构的实现
    发一篇感谢身边的所有从事it工作的朋友
    BeanFactory 默认的注入实现类DefaultListableBeanFactory
    jsSwitch语句优化
    彻底搞懂 Nginx 的五大应用场景
    Spring Boot 整合 Quartz 轻松实现任务调度!
    js计算两个给定日期之间的天数
  • 原文地址:https://www.cnblogs.com/nafio/p/12370173.html
Copyright © 2011-2022 走看看