Lua 中實現 protobuf 序列化,反序列化
https://blog.csdn.net/fanyun7654/article/details/52596000
Protobuf 官方并沒有 Lua版本,然后網易的程序猿開發出了 protoc-gen-lua ,可以讓我們將 Proto 文件轉成 lua 腳本在 Lua中使用,下面是詳細的編譯、安裝、使用教程。文中用到的代碼、工具都有百度網盤下載。
網盤下載地址: http://pan.baidu.com/s/1bo8Ufd9
1、首先我們需要安裝Python2.7,下載地址:
默認安裝到C盤把安裝目錄添加到環境變量中,然后打開命令行 控制臺,輸入命令
如果提示 命令不存在,則說明環境變量沒有設置正確,如果是如下圖,說明設置成功
ame.com.cn
2、下載并編譯 Luajit 2.0.4 ,
下載后解壓,找到 LuaJIT-2.0.4/src 目錄,其中有一個批處理文件 msvcbuild.bat ,這是在 Windows系統的編譯工具。在開始菜單 - 所有應用中的 Visual Studio 201x 中找到 Visual Studio Tools,打開 VS201x 開發人員命令提示,切換到 LuaJIT-2.0.4/src 目錄,執行命令
開始編譯 Luajit 2.0.4
像下圖 出現 Successfully built LuaJIT for Windows/x86 說明編譯成功
本文轉自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
到 LuaJIT-2.0.4\src 目錄中尋找 lua51.dll lua51.lib luajit.exe 這三個文件是否存在,如果上面編譯成功,那這三個文件是一定有的。
3、下載并編譯 protobuf-2.4.1
在 protobuf-2.4.1\vsprojects 目錄中打開 protobuf.sln ,如下圖
在 Visual Studio 中將 下圖中 紅框 中的 test 項目 從項目中移除,要來沒用。
刪除后如下圖
項目一個一個編譯,不要一起編譯。
首先來編譯 libprotobuf 項目,肯定會出錯。提示如下錯誤
原因是Protobuf 中沒有添加對應的頭文件,在項目中 搜索打開 common.h ,添加對應頭文件,如下圖:
再次編譯,就可以編譯成功。
然后編譯 第二個項目 libprotobuf-lite 。不會出錯。
然后再編譯 第三個項目 libprotoc ??隙〞鲥e,如下圖
雙擊定位錯誤,或者打開 command_line_interface.cc ,到913行 ,修改為如下圖
再次編譯,即可成功。
最后編譯第四個 項目 protoc 。編譯成功
然后到 protobuf-2.4.1\vsprojects\Debug 目錄中找到生成的 4 個文件,如下圖紅框中的文件
這4個文件會在 編譯 protoc-gen-lua的時候用到。
編譯成功后,到 protobuf-2.4.1\Python 文件夾中執行命令
4、下載并 編譯安裝 protoc-gen-lua ,
下載解壓后,打開 目錄,如下圖有三個文件夾
在 plugin 目錄 創建 批處理文件 protoc-gen-lua.bat , 內容如下
然后將 上一步 編譯 protobuf-2.4.1 中生成的 protoc.exe 拷貝到 protoc-gen-lua-master 目錄,如下圖
然后在 protoc-gen-lua-master 目錄下創建批處理文件 buildproto.bat ,內容如下
這個批處理的作用是:先進入到一個文件夾,然后將該文件夾中的 proto 文件 生成 lua 文件。 我這里是進入到 protoc-gen-lua-master\protobuf\luascript 。
所以我在 protobuf 目錄下新建 目錄 luascript ,在該目錄進行 proto 轉換 lua 。如果需要在其它目錄進行,要把上面批處理的內容修改目錄為自己想要的。
好,下面來測試一下。
在 protoc-gen-lua-master\example 目錄下有一個測試的 proto 文件 person.proto ,把它拷貝到 luascript 文件夾。
然后 返回執行上面創建的批處理文件 buildproto.bat 。 本文轉自http://blog.csdn.net/huutu http://www.thisisgame.com.cn
生成成功,到 luascript 中查看,看到生成了對應的 lua 文件 person_pb.lua 。
5、編寫工程測試 生成的 protobuf lua 文件
新建一個空項目,把 protoc-gen-lua-master\protobuf\pb.c 加入到項目中。
在 main.cpp 中添加初始化 Lua 以及初始化 proto-lua 的代碼
設置 頭文件引用路徑為 LuaJIT-2.0.4\src 目錄
設置鏈接器附加庫目錄為 LuaJIT-2.0.4\src 目錄
設置鏈接器附加依賴項為 lua5.1.4.lib
然后編譯,肯定會報錯。。如下圖
需要修改 pb.c 的開始部分代碼如下
就是用 宏定義 來判斷,在Windows 系統下不引用 endian.h 這個文件。
再次編譯,肯定成功。
在上面的代碼中,我們加載了一個 lua 腳本文件 main.lua 。
我們在項目目錄中新建 main.lua 并添加如下代碼
在 lua 代碼里面,我們 測試了 對 person 的序列化 和 反序列化 。
還記得之前生成的 person_pb.lua 文件嗎?在 protoc-gen-lua-master\protobuf\luascript 目錄里。
我們把整個 protoc-gen-lua-master\protobuf 目錄拷貝到測試項目 目錄 里來。因為 main.lua 中要引用這些 lua 文件。
然后運行測試項目
序列化 和 反序列化 測試成功
測試工程下載
至此, protoc-gen-lua 編譯 測試使用完畢
在lua環境中使用protobuf
https://blog.csdn.net/mergerly/article/details/16350871
最近在cocos2dx的項目中,需要在LUA腳本層使用protobuf協議。官方已經推出了很多種語言的版本。但唯獨LUA版本不全。于是開始研究protobuf在LUA下的實現,將完整的過程記錄了下來,希望對其它人能有所幫助。
1、下載protoc-gen-lua
可以通過HG從服務器(hg clone https://code.google.com/p/protoc-gen-lua/)上下載最新的版本。
簡單介紹一下里面的三個目錄:
example 存放的一個示例協議,
plugin 將.proto協議轉為LUA腳本需要的工具。要注意,這個工具是用PYTHON寫的,所以后面我們需要安裝PYTHON。
rotobuf這里存放了工程需要的文件。其中pb.c是C碼文件。主要是在工程中引用,也可以編譯成動態文件(.so)供LUA調用。其它LUA文件則需要引入到LUA工程中。
2、安裝PYTHON27。推薦是這個版本。
3、下載protobuf然后編譯出protoc.exe。
可以用SVN從服務器上(http://protobuf.googlecode.com/svn/trunk)下載最新的protobuf。我使用的是protobuf-2.4.1。
進入protobuf-2.4.1/vsprojects利用VS2010進行編譯。生成的protoc.exe放到protobuf-2.4.1/src下。如果不放,后面無法安裝python版的protobuf。
4、編譯python版本的protobuf
在protobuf-2.4.1\python下運行python setup.py build,然后再執行python setup.py install。
注意:如果第3步的protoc.exe沒有放,會出現錯誤找不到google\protobuf\compiler目錄。
5、制作轉換協議的批處理
在protoc-gen-lua/plugin目錄下編寫批處理:protoc-gen-lua.bat,就下面一行代碼。
///////////////////////////////////////////////////////////////////////////////////////
@python "%~dp0protoc-gen-lua"
///////////////////////////////////////////////////////////////////////////////////////
但要確保你的python命令能正常運行。否則將python.exe所在的目錄加到環境變量path中。
接著拷貝一份protoc.exe到protoc-gen-lua目錄。第3步我們已經編譯了出了protoc.exe。在協議轉換中,我們需要使用他。
在protoc-gen-lua目錄編寫批處理:buildproto.bat 來轉換協議。
請正確指定protoc.exe和protoc-gen-lua.bat相對協議目錄的路徑。
6、轉換協議文件
protoc-gen-lua/example目錄中,有一個協議文件person.proto,可以拿他做一下試驗,會生成一個person_pb.lua
7、編譯pb.c文件
protoc-gen-lua/protobuf目錄中有一個pb.c文件。我們需要用他來協助lua完成protobuf的功能。
用vs2010新建一個控制臺程序。將pb.c加入到工程中。在windows平臺下,要對pb.c做如下修改。
1)將 #include <endian.h>修改為
#ifndef _WIN32
#include <endian.h>
#endif
避免在windows下缺失文件報錯.
2)調整struct_unpack函數前幾行為
static int struct_unpack(lua_State *L)
{
uint8_t format = luaL_checkinteger(L, 1);
size_t len;
const uint8_t* buffer = (uint8_t*)luaL_checklstring(L, 2, &len);
size_t pos = luaL_checkinteger(L, 3);
uint8_t out[8];
buffer += pos;
3)在主函數前面申明pb.c的入口。
extern "C" { int luaopen_pb (lua_State *L);} // 注意防在命名空間外的全局聲明
編寫主函數如下:
工程需要lua5.1.lib的接入。這個請自行編譯。
8、編寫main.lua。
也就是測試文件,可以參考protoc-gen-lua/example中的test.lua。
9、測試
編譯并運行VS工程。運行目錄應該是LUA文件所在的目錄。運行結果如下:
10、總結。
這里實現了,在C++中搭建lua的protobuf環境。但未實現純粹的Lua-protobuf環境。
如果需要在LUA中實現protobuf,那需要自己將pb.c編譯成dll。在linux下需要利用protoc-gen-lua/protobuf中的makefile將pb.c編譯成pb.so。
然后將pb.so或pb.dll導入到lua工程中。然后在main.lua中調用pb.c中的入口,代碼如下:
理論上是這樣,我還沒有做詳細的測試。如果有進展,再完善本貼。
轉自:http://blog.csdn.net/sunshine7858/article/details/9260671
-----------------------------------------------------------------------------------------------
下載地址:
http://code.google.com/p/protobuf/downloads/list
安裝命令
tar -xzf protobuf-2.5.0.tar.gz
cd protobuf-2.5.0
./configure --prefix=$INSTALL_DIR
make
make check
make install
然后進入python目錄,
python setup.py install --prefix=$INSTALL_DIR
寫proto文件
package lm;
message Person
{
required int32 id = 1;
required string str = 2;
optional int32 opt = 3;
}
保存為 testp.testpb.proto
編譯指令
protoc -I=/home/workspace/testprob --python_out=/home/workspace/testprob /home/workspace/testprob/testp.testpb.proto
https://developers.google.com/protocol-buffers/docs/pythontutorial
報錯
package directory 'google/protobuf/compiler' does not exist
解決
https://groups.google.com/forum/?fromgroups=#!topic/protobuf/YeT5RW4qCxY
python ./setup.py build
sudo python ./setup.py install
報錯
File "/home/workspace/testprob/testp/testpb_pb2.py", line 6, in <module>
from google.protobuf import reflection as _reflection
File "build/bdist.linux-i686/egg/google/protobuf/reflection.py", line 68, in <module>
File "build/bdist.linux-i686/egg/google/protobuf/internal/python_message.py"
ImportError: cannot import name enum_type_wrapper
解決
http://code.google.com/p/protobuf/issues/detail?id=438
Log message
Fix issue 438 : add missing 'enum_type_wrapper' to setup.py
是安裝包的一個改進文件,copy下來, 重新安裝
根據安裝目錄下的demo 自己改寫了個簡單的, 覺得它那個還是麻煩
write.py
import testpb_pb4
import sys
p = testpb_pb2.Person()
try:
f = open(sys.argv[1], "rb")
p.ParseFromString(f.read())
f.close()
except IOError:
print sys.argv[1] + ": File not found. Creating a new file."
p.id = 32
p.str = "test"
f = open(sys.argv[1], "wb")
f.write(p.SerializeToString())
f.close()
print "write success"
編譯指令 python write.py "test"
read.py
import sys
import testpb_pb2
if len(sys.argv) != 2:
print "Usage:", sys.argv[0], "ADDRESS_BOOK_FILE"
sys.exit(-1)
p = testpb_pb2.Person()
f = open(sys.argv[1], "rb")
p.ParseFromString(f.read())
f.close()
print "p.str = ", p.str
print "p.id=", p.id
編譯指令 python read.py "test"
--------------------------------------------------------------------------------------------------------------------
LuaJIT下載:
http://luajit.org/download/LuaJIT-2.1.0-beta3.zip
.lib轉換為.a之后MinGW編譯引用(Windows平臺)
http://www.shnenglu.com/kenkao/archive/2018/06/13/215724.html
protobuf_lua及pb.dll:(建議使用mingw編譯)
http://www.shnenglu.com/Files/kenkao/protobuf_lua.zip
openresty環境直接在nginx.conf中設置lua的腳本引用路徑及庫路徑:
lua_package_path 'lua/?.lua;pb/?.lua;';
lua_package_cpath '/usr/local/lib/lua/5.1/?.so;';