使用 pbc

来源:互联网 发布:艳照门 张柏芝 知乎 编辑:程序博客网 时间:2024/06/08 15:26
 

使用pbc

标签: linuxluaC++pbc
 1486人阅读 评论(0) 收藏 举报
 分类:
 

目录(?)[+]



1环境

Linux CentOS 7
lua 5.3.1


pbc
GITHUB : https://github.com/cloudwu/pbc
WIKI : http://blog.codingnow.com/2011/12/protocol_buffers_for_c.html


2修改enum类型

将云风的pbc应用到项目中,修改了enum为数字类型,在pbc源码的binding/lua53/pbc-lua53.c 中的


binding/lua53/pbc-lua53.c

[cpp] view plain copy
  1. static void     
  2. push_value(lua_State *L, int type, const char * type_name, union pbc_value *v) {  
  3.     switch(type) {  
  4.     case PBC_FIXED32:  
  5.     case PBC_INT:  
  6.         lua_pushinteger(L, (int)v->i.low);  
  7.         break;  
  8.     case PBC_REAL:  
  9.         lua_pushnumber(L, v->f);  
  10.         break;  
  11.     case PBC_BOOL:  
  12.         lua_pushboolean(L, v->i.low);  
  13.         break;  
  14.     case PBC_ENUM:                                                                                                                                                                             
  15.         //lua_pushstring(L, v->e.name);  
  16.         lua_pushinteger(L, v->e.id);  
  17.         break;  
  18.     case PBC_BYTES:  
  19.     case PBC_STRING:  
  20.         lua_pushlstring(L, (const char *)v->s.buffer , v->s.len);  
  21.         break;  
  22.     case PBC_MESSAGE:  
  23. ...  


binding/lua53/pbc-lua53.c中与PBC_ENUM相关的函数都改为使用int

binding/lua53/pbc-lua53.c

[cpp] view plain copy
  1. --[[                   
  2. #define PBC_INT 1   
  3. #define PBC_REAL 2  
  4. #define PBC_BOOL 3  
  5. #define PBC_ENUM 4  
  6. #define PBC_STRING 5  
  7. #define PBC_MESSAGE 6  
  8. #define PBC_FIXED64 7  
  9. #define PBC_FIXED32 8  
  10. #define PBC_BYTES 9  
  11. #define PBC_INT64 10  
  12. #define PBC_UINT 11  
  13. #define PBC_UNKNOWN 12  
  14. #define PBC_REPEATED 128  
  15. ]]                     
  16.                        
  17. _reader[1] = function(msg) return _reader.int end   
  18. _reader[2] = function(msg) return _reader.real end   
  19. _reader[3] = function(msg) return _reader.bool end   
  20. --_reader[4] = function(msg) return _reader.string end  
  21. _reader[4] = function(msg) return _reader.int end   
  22. _reader[5] = function(msg) return _reader.string end   
  23. _reader[6] = function(msg)  
  24.     local message = _reader.message  
  25.     return  function(self,key)  
  26.             return message(self, key, msg)  
  27.         end            
  28. end      
  29. ...  


3重新编译动态库

pbc/
make
pbc/binding/lua53
make

得到protobuf.so

如下图所示




4 测试用例

修改后的protobuf.lua
[plain] view plain copy
  1. local c = require "protobuf.c"  
  2.   
  3. local setmetatable = setmetatable  
  4. local type = type  
  5. local table = table  
  6. local assert = assert  
  7. local pairs = pairs  
  8. local ipairs = ipairs  
  9. local string = string  
  10. local print = print  
  11. local io = io  
  12. local tinsert = table.insert  
  13. local rawget = rawget  
  14.   
  15. local M = {}  
  16.   
  17. local _pattern_cache = {}  
  18.   
  19. local P,GC  
  20.   
  21. P = debug.getregistry().PROTOBUF_ENV  
  22.   
  23. if P then  
  24.     GC = c._gc()  
  25. else  
  26.     P= c._env_new()  
  27.     GC = c._gc(P)  
  28. end  
  29.   
  30. M.GC = GC  
  31.   
  32. function M.lasterror()  
  33.     return c._last_error(P)  
  34. end  
  35.   
  36. local decode_type_cache = {}  
  37. local _R_meta = {}  
  38.   
  39. function _R_meta:__index(key)  
  40.     local v = decode_type_cache[self._CType][key](self, key)  
  41.     self[key] = v  
  42.     return v  
  43. end  
  44.   
  45. local _reader = {}  
  46.   
  47. function _reader:real(key)  
  48.     return c._rmessage_real(self._CObj , key , 0)  
  49. end  
  50.   
  51. function _reader:string(key)  
  52.     return c._rmessage_string(self._CObj , key , 0)  
  53. end  
  54.   
  55. function _reader:bool(key)  
  56.     return c._rmessage_int(self._CObj , key , 0) ~= 0  
  57. end  
  58.   
  59. function _reader:message(key, message_type)  
  60.     local rmessage = c._rmessage_message(self._CObj , key , 0)  
  61.     if rmessage then  
  62.         local v = {  
  63.             _CObj = rmessage,  
  64.             _CType = message_type,  
  65.             _Parent = self,  
  66.         }  
  67.         return setmetatable( v , _R_meta )  
  68.     end  
  69. end  
  70.   
  71. function _reader:int(key)  
  72.     return c._rmessage_int(self._CObj , key , 0)  
  73. end  
  74.   
  75. function _reader:real_repeated(key)  
  76.     local cobj = self._CObj  
  77.     local n = c._rmessage_size(cobj , key)  
  78.     local ret = {}  
  79.     for i=0,n-1 do  
  80.         tinsert(ret,  c._rmessage_real(cobj , key , i))  
  81.     end  
  82.     return ret  
  83. end  
  84.   
  85. function _reader:string_repeated(key)  
  86.     local cobj = self._CObj  
  87.     local n = c._rmessage_size(cobj , key)  
  88.     local ret = {}  
  89.     for i=0,n-1 do  
  90.         tinsert(ret,  c._rmessage_string(cobj , key , i))  
  91.     end  
  92.     return ret  
  93. end  
  94.   
  95. function _reader:bool_repeated(key)  
  96.     local cobj = self._CObj  
  97.     local n = c._rmessage_size(cobj , key)  
  98.     local ret = {}  
  99.     for i=0,n-1 do  
  100.         tinsert(ret,  c._rmessage_int(cobj , key , i) ~= 0)  
  101.     end  
  102.     return ret  
  103. end  
  104.   
  105. function _reader:message_repeated(key, message_type)  
  106.     local cobj = self._CObj  
  107.     local n = c._rmessage_size(cobj , key)  
  108.     local ret = {}  
  109.     for i=0,n-1 do  
  110.         local m = {  
  111.             _CObj = c._rmessage_message(cobj , key , i),  
  112.             _CType = message_type,  
  113.             _Parent = self,  
  114.         }  
  115.         tinsert(ret, setmetatable( m , _R_meta ))  
  116.     end  
  117.     return ret  
  118. end  
  119.   
  120. function _reader:int_repeated(key)  
  121.     local cobj = self._CObj  
  122.     local n = c._rmessage_size(cobj , key)  
  123.     local ret = {}  
  124.     for i=0,n-1 do  
  125.         tinsert(ret,  c._rmessage_int(cobj , key , i))  
  126.     end  
  127.     return ret  
  128. end  
  129.   
  130. --[[  
  131. #define PBC_INT 1  
  132. #define PBC_REAL 2  
  133. #define PBC_BOOL 3  
  134. #define PBC_ENUM 4  
  135. #define PBC_STRING 5  
  136. #define PBC_MESSAGE 6  
  137. #define PBC_FIXED64 7  
  138. #define PBC_FIXED32 8  
  139. #define PBC_BYTES 9  
  140. #define PBC_INT64 10  
  141. #define PBC_UINT 11  
  142. #define PBC_UNKNOWN 12  
  143. #define PBC_REPEATED 128  
  144. ]]  
  145.   
  146. _reader[1] = function(msg) return _reader.int end  
  147. _reader[2] = function(msg) return _reader.real end  
  148. _reader[3] = function(msg) return _reader.bool end  
  149. --_reader[4] = function(msg) return _reader.string end  
  150. _reader[4] = function(msg) return _reader.int end  
  151. _reader[5] = function(msg) return _reader.string end  
  152. _reader[6] = function(msg)  
  153.     local message = _reader.message  
  154.     return  function(self,key)  
  155.             return message(self, key, msg)  
  156.         end  
  157. end  
  158. _reader[7] = _reader[1]  
  159. _reader[8] = _reader[1]  
  160. _reader[9] = _reader[5]  
  161. _reader[10] = _reader[7]  
  162. _reader[11] = _reader[7]  
  163.   
  164. _reader[128+1] = function(msg) return _reader.int_repeated end  
  165. _reader[128+2] = function(msg) return _reader.real_repeated end  
  166. _reader[128+3] = function(msg) return _reader.bool_repeated end  
  167. --_reader[128+4] = function(msg) return _reader.string_repeated end  
  168. _reader[128+4] = function(msg) return _reader.int_repeated end  
  169. _reader[128+5] = function(msg) return _reader.string_repeated end  
  170. _reader[128+6] = function(msg)  
  171.     local message = _reader.message_repeated  
  172.     return  function(self,key)  
  173.             return message(self, key, msg)  
  174.         end  
  175. end  
  176. _reader[128+7] = _reader[128+1]  
  177. _reader[128+8] = _reader[128+1]  
  178. _reader[128+9] = _reader[128+5]  
  179. _reader[128+10] = _reader[128+7]  
  180. _reader[128+11] = _reader[128+7]  
  181.   
  182. local _decode_type_meta = {}  
  183.   
  184. function _decode_type_meta:__index(key)  
  185.     local t, msg = c._env_type(P, self._CType, key)  
  186.     local func = assert(_reader[t],key)(msg)  
  187.     self[key] = func  
  188.     return func  
  189. end  
  190.   
  191. setmetatable(decode_type_cache , {  
  192.     __index = function(self, key)  
  193.         local v = setmetatable({ _CType = key } , _decode_type_meta)  
  194.         self[key] = v  
  195.         return v  
  196.     end  
  197. })  
  198.   
  199. local function decode_message( message , buffer, length)  
  200.     local rmessage = c._rmessage_new(P, message, buffer, length)  
  201.     if rmessage then  
  202.         local self = {  
  203.             _CObj = rmessage,  
  204.             _CType = message,  
  205.         }  
  206.         c._add_rmessage(GC,rmessage)  
  207.         return setmetatable( self , _R_meta )  
  208.     end  
  209. end  
  210.   
  211. ----------- encode ----------------  
  212.   
  213. local encode_type_cache = {}  
  214.   
  215. local function encode_message(CObj, message_type, t)  
  216.     local type = encode_type_cache[message_type]  
  217.     for k,v in pairs(t) do  
  218.         local func = type[k]  
  219.         func(CObj, k , v)  
  220.     end  
  221. end  
  222.   
  223. local _writer = {  
  224.     real = c._wmessage_real,  
  225.     --enum = c._wmessage_string,  
  226.     enum = c._wmessage_int,  
  227.     string = c._wmessage_string,  
  228.     int = c._wmessage_int,  
  229. }  
  230.   
  231. function _writer:bool(k,v)  
  232.     c._wmessage_int(self, k, v and 1 or 0)  
  233. end  
  234.   
  235. function _writer:message(k, v , message_type)  
  236.     local submessage = c._wmessage_message(self, k)  
  237.     encode_message(submessage, message_type, v)  
  238. end  
  239.   
  240. function _writer:real_repeated(k,v)  
  241.     for _,v in ipairs(v) do  
  242.         c._wmessage_real(self,k,v)  
  243.     end  
  244. end  
  245.   
  246. function _writer:bool_repeated(k,v)  
  247.     for _,v in ipairs(v) do  
  248.         c._wmessage_int(self, k, v and 1 or 0)  
  249.     end  
  250. end  
  251.   
  252. function _writer:string_repeated(k,v)  
  253.     for _,v in ipairs(v) do  
  254.         c._wmessage_string(self,k,v)  
  255.     end  
  256. end  
  257.   
  258. function _writer:message_repeated(k,v, message_type)  
  259.     for _,v in ipairs(v) do  
  260.         local submessage = c._wmessage_message(self, k)  
  261.         encode_message(submessage, message_type, v)  
  262.     end  
  263. end  
  264.   
  265. function _writer:int_repeated(k,v)  
  266.     for _,v in ipairs(v) do  
  267.         c._wmessage_int(self,k,v)  
  268.     end  
  269. end  
  270.   
  271. _writer[1] = function(msg) return _writer.int end  
  272. _writer[2] = function(msg) return _writer.real end  
  273. _writer[3] = function(msg) return _writer.bool end  
  274. --_writer[4] = function(msg) return _writer.string end  
  275. _writer[4] = function(msg) return _writer.int end  
  276. _writer[5] = function(msg) return _writer.string end  
  277. _writer[6] = function(msg)  
  278.     local message = _writer.message  
  279.     return  function(self,key , v)  
  280.             return message(self, key, v, msg)  
  281.         end  
  282. end  
  283. _writer[7] = _writer[1]  
  284. _writer[8] = _writer[1]  
  285. _writer[9] = _writer[5]  
  286. _writer[10] = _writer[7]  
  287. _writer[11] = _writer[7]  
  288.   
  289. _writer[128+1] = function(msg) return _writer.int_repeated end  
  290. _writer[128+2] = function(msg) return _writer.real_repeated end  
  291. _writer[128+3] = function(msg) return _writer.bool_repeated end  
  292. --_writer[128+4] = function(msg) return _writer.string_repeated end  
  293. _writer[128+4] = function(msg) return _writer.int_repeated end  
  294. _writer[128+5] = function(msg) return _writer.string_repeated end  
  295. _writer[128+6] = function(msg)  
  296.     local message = _writer.message_repeated  
  297.     return  function(self,key, v)  
  298.             return message(self, key, v, msg)  
  299.         end  
  300. end  
  301.   
  302. _writer[128+7] = _writer[128+1]  
  303. _writer[128+8] = _writer[128+1]  
  304. _writer[128+9] = _writer[128+5]  
  305. _writer[128+10] = _writer[128+7]  
  306. _writer[128+11] = _writer[128+7]  
  307.   
  308. local _encode_type_meta = {}  
  309.   
  310. function _encode_type_meta:__index(key)  
  311.     local t, msg = c._env_type(P, self._CType, key)  
  312.     local func = assert(_writer[t],key)(msg)  
  313.     self[key] = func  
  314.     return func  
  315. end  
  316.   
  317. setmetatable(encode_type_cache , {  
  318.     __index = function(self, key)  
  319.         local v = setmetatable({ _CType = key } , _encode_type_meta)  
  320.         self[key] = v  
  321.         return v  
  322.     end  
  323. })  
  324.   
  325. function M.encode( message, t , func , ...)  
  326.     local encoder = c._wmessage_new(P, message)  
  327.     assert(encoder ,  message)  
  328.     encode_message(encoder, message, t)  
  329.     if func then  
  330.         local buffer, len = c._wmessage_buffer(encoder)  
  331.         local ret = func(buffer, len, ...)  
  332.         c._wmessage_delete(encoder)  
  333.         return ret  
  334.     else  
  335.         local s = c._wmessage_buffer_string(encoder)  
  336.         c._wmessage_delete(encoder)  
  337.         return s  
  338.     end  
  339. end  
  340.   
  341. --------- unpack ----------  
  342.   
  343. local _pattern_type = {  
  344.     [1] = {"%d","i"},  
  345.     [2] = {"%F","r"},  
  346.     [3] = {"%d","b"},  
  347.     [5] = {"%s","s"},  
  348.     [6] = {"%s","m"},  
  349.     [7] = {"%D","d"},  
  350.     [128+1] = {"%a","I"},  
  351.     [128+2] = {"%a","R"},  
  352.     [128+3] = {"%a","B"},  
  353.     [128+5] = {"%a","S"},  
  354.     [128+6] = {"%a","M"},  
  355.     [128+7] = {"%a","D"},  
  356. }  
  357.   
  358. _pattern_type[4] = _pattern_type[1]  
  359. _pattern_type[8] = _pattern_type[1]  
  360. _pattern_type[9] = _pattern_type[5]  
  361. _pattern_type[10] = _pattern_type[7]  
  362. _pattern_type[11] = _pattern_type[7]  
  363. _pattern_type[128+4] = _pattern_type[128+1]  
  364. _pattern_type[128+8] = _pattern_type[128+1]  
  365. _pattern_type[128+9] = _pattern_type[128+5]  
  366. _pattern_type[128+10] = _pattern_type[128+7]  
  367. _pattern_type[128+11] = _pattern_type[128+7]  
  368.   
  369.   
  370. local function _pattern_create(pattern)  
  371.     local iter = string.gmatch(pattern,"[^ ]+")  
  372.     local message = iter()  
  373.     local cpat = {}  
  374.     local lua = {}  
  375.     for v in iter do  
  376.         local tidx = c._env_type(P, message, v)  
  377.         local t = _pattern_type[tidx]  
  378.         assert(t,tidx)  
  379.         tinsert(cpat,v .. " " .. t[1])  
  380.         tinsert(lua,t[2])  
  381.     end  
  382.     local cobj = c._pattern_new(P, message , "@" .. table.concat(cpat," "))  
  383.     if cobj == nil then  
  384.         return  
  385.     end  
  386.     c._add_pattern(GC, cobj)  
  387.     local pat = {  
  388.         CObj = cobj,  
  389.         format = table.concat(lua),  
  390.         size = 0  
  391.     }  
  392.     pat.size = c._pattern_size(pat.format)  
  393.   
  394.     return pat  
  395. end  
  396.   
  397. setmetatable(_pattern_cache, {  
  398.     __index = function(t, key)  
  399.         local v = _pattern_create(key)  
  400.         t[key] = v  
  401.         return v  
  402.     end  
  403. })  
  404.   
  405. function M.unpack(pattern, buffer, length)  
  406.     local pat = _pattern_cache[pattern]  
  407.     return c._pattern_unpack(pat.CObj , pat.format, pat.size, buffer, length)  
  408. end  
  409.   
  410. function M.pack(pattern, ...)  
  411.     local pat = _pattern_cache[pattern]  
  412.     return c._pattern_pack(pat.CObj, pat.format, pat.size , ...)  
  413. end  
  414.   
  415. function M.check(typename , field)  
  416.     if field == nil then  
  417.         return c._env_type(P,typename)  
  418.     else  
  419.         return c._env_type(P,typename,field) ~=0  
  420.     end  
  421. end  
  422.   
  423. --------------  
  424.   
  425. local default_cache = {}  
  426.   
  427. -- todo : clear default_cache, v._CObj  
  428.   
  429. local function default_table(typename)  
  430.     local v = default_cache[typename]  
  431.     if v then  
  432.         return v  
  433.     end  
  434.   
  435.     v = { __index = assert(decode_message(typename , "")) }  
  436.   
  437.     default_cache[typename]  = v  
  438.     return v  
  439. end  
  440.   
  441. local decode_message_mt = {}  
  442.   
  443. local function decode_message_cb(typename, buffer)  
  444.     return setmetatable ( { typename, buffer } , decode_message_mt)  
  445. end  
  446.   
  447. function M.decode(typename, buffer, length)  
  448.     local ret = {}  
  449.     local ok = c._decode(P, decode_message_cb , ret , typename, buffer, length)  
  450.     if ok then  
  451.         return setmetatable(ret , default_table(typename))  
  452.     else  
  453.         return false , c._last_error(P)  
  454.     end  
  455. end  
  456.   
  457. local function expand(tbl)  
  458.     local typename = rawget(tbl , 1)  
  459.     local buffer = rawget(tbl , 2)  
  460.     tbl[1] , tbl[2] = nil , nil  
  461.     assert(c._decode(P, decode_message_cb , tbl , typename, buffer), typename)  
  462.     setmetatable(tbl , default_table(typename))  
  463. end  
  464.   
  465. function decode_message_mt.__index(tbl, key)  
  466.     expand(tbl)  
  467.     return tbl[key]  
  468. end  
  469.   
  470. function decode_message_mt.__pairs(tbl)  
  471.     expand(tbl)  
  472.     return pairs(tbl)  
  473. end  
  474.   
  475. local function set_default(typename, tbl)  
  476.     for k,v in pairs(tbl) do  
  477.         if type(v) == "table" then  
  478.             local t, msg = c._env_type(P, typename, k)  
  479.             if t == 6 then  
  480.                 set_default(msg, v)  
  481.             elseif t == 128+6 then  
  482.                 for _,v in ipairs(v) do  
  483.                     set_default(msg, v)  
  484.                 end  
  485.             end  
  486.         end  
  487.     end  
  488.     return setmetatable(tbl , default_table(typename))  
  489. end  
  490.   
  491. function M.register(buffer)  
  492.     c._env_register(P, buffer)  
  493. end  
  494.   
  495. function M.register_file(filename)  
  496.     local f = assert(io.open(filename , "rb"))  
  497.     local buffer = f:read "*a"  
  498.     c._env_register(P, buffer)  
  499.     f:close()  
  500. end  
  501.   
  502. function M.enum_id(enum_type, enum_name)  
  503.     return c._env_enum_id(P, enum_type, enum_name)  
  504. end  
  505.   
  506. function M.extract(tbl)  
  507.     local typename = rawget(tbl , 1)  
  508.     local buffer = rawget(tbl , 2)  
  509.     if type(typename) == "string" and type(buffer) == "string" then  
  510.         if M.check(typename) then  
  511.             expand(tbl)  
  512.         end  
  513.     end  
  514.   
  515.     for k, v in pairs(tbl) do  
  516.         if type(v) == "table" then  
  517.             M.extract(v)  
  518.         end  
  519.     end  
  520. end  
  521.   
  522. M.default=set_default  
  523.   
  524. function M.new(typename, tbl)  
  525.     local tbl = tbl or {}  
  526.   
  527.     return setmetatable(tbl , default_table(typename))  
  528. end  
  529.   
  530. function M.serializeToString(msg)  
  531.     return decode(msg._CType, msg)  
  532. end  
  533.   
  534. return M  




addressbook.proto
[plain] view plain copy
  1. <span style="font-size:18px;">// See README.txt for information and build instructions.  
  2. syntax = "proto2";  
  3. package tutorial;  
  4.   
  5. enum Cmd  
  6. {  
  7.     GAMECMD  = 1;  
  8.     SCENECMD = 2;  
  9. }  
  10.   
  11. message Person {  
  12.   required string name = 1;  
  13.   required int32 id = 2;        // Unique ID number for this person.  
  14.   optional string email = 3;  
  15.   
  16.   enum PhoneType {  
  17.     MOBILE = 0;  
  18.     HOME = 1;  
  19.     WORK = 2;  
  20.   }  
  21.   
  22.   message PhoneNumber {  
  23.     required string number = 1;  
  24.     optional PhoneType type = 2 [default = WORK];  
  25.   }  
  26.   
  27.   repeated PhoneNumber phone = 4;  
  28.   repeated int32 test = 5 [packed=true];  
  29.   optional uint32 score = 6;  
  30.   optional PhoneType tel = 7;  
  31.   repeated string params = 8;  
  32.   optional Cmd cmd1 = 9[default = GAMECMD];  
  33.   required Cmd cmd2 = 10[default = GAMECMD];  
  34.   optional bytes data = 11;  
  35.   
  36.   extensions 100 to max;   
  37. }  
  38.   
  39. message Ext {  
  40.   extend Person {  
  41.     optional int32 test = 100;  
  42.   }  
  43. }  
  44.   
  45. // Our address book file is just one of these.  
  46. message AddressBook {  
  47.   repeated Person person = 1;  
  48. }  
  49. </span>  


main.cpp
[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include "addressbook.pb.h"  
  3.   
  4. extern "C"  
  5. {  
  6.   #include <lua.h>  
  7.   #include <lauxlib.h>  
  8.   #include <lualib.h>  
  9. }  
  10.   
  11. int parseWithLuaPBC(lua_State* L, std::string& strMsg)  
  12. {  
  13.     lua_getglobal(L, "parseWithPBC");  
  14.     lua_pushstring(L, strMsg.c_str());  
  15.     lua_call(L, 1, 1);  
  16.   
  17.     int ret = (int)lua_tointeger(L, -1);  
  18.     lua_pop(L, 1);  
  19.   
  20.     return ret;  
  21. }  
  22.   
  23. int add(lua_State* L)  
  24. {  
  25.     lua_getglobal(L, "add");  
  26.     lua_pushnumber(L, 1);  
  27.     lua_pushnumber(L, 1);  
  28.     lua_call(L, 2, 1);  
  29.   
  30.     int ret = (int)lua_tointeger(L, -1);  
  31.     lua_pop(L, 1);  
  32.   
  33.     printf("ret : %d\n", ret);  
  34.   
  35.     return 0;  
  36. }  
  37.   
  38. static int parseFromPBC(lua_State* L)  
  39. {  
  40.     const char* pmsg = luaL_checkstring(L, 1);  
  41.     std::string strMsg = pmsg;   
  42.   
  43.     tutorial::Person p;  
  44.     p.ParseFromString(strMsg);  
  45.   
  46.     printf("%d\n", (int)p.id());  
  47.     printf("%s\n", p.name().c_str());  
  48.     printf("%d\n", (int)p.tel());  
  49.   
  50.     printf("%d\n", (int)p.phone_size());  
  51.   
  52.     for (int i = 0; i < (int)p.phone_size(); ++i)  
  53.     {  
  54.         const tutorial::Person_PhoneNumber& phone = p.phone(i);  
  55.         printf("number : %s\ttype : %d\n", phone.number().c_str(), (int)phone.type());  
  56.     }  
  57.   
  58.     for (int i = 0; i < (int)p.params_size(); ++i)  
  59.     {  
  60.         const std::string& str = p.params(i);  
  61.         printf("param %s\n", str.c_str());  
  62.     }  
  63.   
  64.     const std::string& strData = p.data();  
  65.     printf("data %s\n", strData.c_str());  
  66.   
  67.     return 0;  
  68. }  
  69.   
  70. int main( void )  
  71. {  
  72.     lua_State *L = luaL_newstate();  
  73.     luaL_openlibs( L );  
  74.       
  75.     lua_register(L, "parseFromPBC", parseFromPBC);  
  76.   
  77.     luaL_dofile(L, "test.lua");  
  78.   
  79.     tutorial::Person p;  
  80.     p.set_name("chenjielin");  
  81.     p.set_id(101);  
  82.     p.set_email("chenjielin@xindong.com");  
  83.   
  84.     std::string strMsg;  
  85.     p.SerializeToString(&strMsg);  
  86.     parseWithLuaPBC(L, strMsg);  
  87.   
  88.       
  89.     lua_close( L );  
  90.     return 0;  
  91. }  

test.lua
[plain] view plain copy
  1. local protobuf = require "protobuf"  
  2.   
  3. addr = io.open("addressbook.pb","rb")  
  4. buffer = addr:read "*a"  
  5. addr:close()  
  6.   
  7. protobuf.register(buffer)  
  8.   
  9. t = protobuf.decode("google.protobuf.FileDescriptorSet", buffer)  
  10.   
  11. proto = t.file[1]  
  12.   
  13. person = {  
  14.     name = "Alice",  
  15.     id = 12345,  
  16.     phone = {  
  17.         { number = 17712345678, type = 1 },  
  18.         { number = 17712345678, type = 2 },  
  19.     },  
  20.     tel = 2,  
  21.     --[[  
  22.     params = {  
  23.         [1] = "chen",  
  24.         [2] = "jie",  
  25.         [3] = "lin"  
  26.     },  
  27.     --]]  
  28.     cmd2 = 1,  
  29.     data = "1010"  
  30. }  
  31.   
  32. code = protobuf.encode("tutorial.Person", person)  
  33.   
  34. parseFromPBC(code)  
  35.   
  36. decode = protobuf.decode("tutorial.Person" , code)  
  37.   
  38. --[[  
  39. for k,v in pairs(decode) do  
  40.     print(k,v)  
  41.     if type(v) == "table" then  
  42.         for ck, cv in pairs(v) do  
  43.             print("", ck, cv)  
  44.         end  
  45.     end  
  46. end  
  47. --]]  
  48.   
  49. print("cmd1", decode.cmd1)  
  50. print("data", decode.data)  
  51.   
  52. print("params len", #decode.params)  
  53.   
  54. if getmetatable(decode) then  
  55.     local mt = getmetatable(decode)  
  56.     for k,v in pairs(mt) do  
  57.         print(k,v)  
  58.         if type(v) == "table" then  
  59.             for ck,cv in pairs(v) do  
  60.                 print("", ck,cv)  
  61.             end  
  62.         end  
  63.     end  
  64. end  
  65.   
  66. --print(decode.name)  
  67. --print(decode.id)  
  68.   
  69.   
  70. print("###################")  
  71.   
  72. local msg = protobuf.new("tutorial.Person")  
  73.   
  74. print(msg._CType)  
  75. print(msg.params)  
  76. print(msg.phone)  
  77. print(msg.cmd1)  
  78. print(msg.cmd2)  
  79.   
  80. for k,v in pairs(msg) do  
  81.     print(k,v)  
  82. end  
  83.   
  84. function parseWithPBC(data)  
  85.     print("---------")  
  86.     local msg = protobuf.decode("tutorial.Person", data)  
  87.     if msg then  
  88.         print(msg.cmd1)  
  89.         print(msg.name)  
  90.         print(msg.email)  
  91.     end  
  92.   
  93.     return 1  
  94. end  

Makefile
[plain] view plain copy
  1. TARGET=test  
  2. TARGET:main.o addressbook.pb.o  
  3.     g++ -I/usr/local/include/ -L/usr/local/lib/ -lm -DLUA_USE_READLINE main.o addressbook.pb.o -o $(TARGET) -g -Wl,-E -ldl -llua -lprotobuf -Wl,-Bstatic -Wl,-Bdynamic -lpthread  
  4. main.o:main.cpp  
  5. addressbook.pb.o:addressbook.pb.cc  
  6. clean:  
  7.     rm -rf $(TARGET)  
  8.     rm -rf *.o  
  9. clear:  
  10.     rm -rf core*  
  11.     rm -rf *.pb*  
  12.       

生成pb脚本
proto.sh
[plain] view plain copy
  1. #!/bin/bash  
  2.   
  3. protoc -o addressbook.pb addressbook.proto  
  4. protoc --cpp_out=./ addressbook.proto  



5运行效果


原创粉丝点击