【轉】 cocos2dx 3.x C++搭建protobuf環境

http://blog.csdn.net/ganpengjin1/article/details/50964961java

Cocos2dx 裏面在網絡遊戲通訊這一塊通常咱們都會採用protobuf來進行通訊,cocos引擎沒有集成C++的protobuf,那咱們只能本身來集成了。由於protobuf有不少版本,那麼咱們怎麼去下載與引擎中想對應的protobuf版本呢。python

他在android

[cpp]  view plain  copy
 
  1. cocos2d-x\tools\simulator\libsimulator\lib\protobuf-lite  

在這裏目錄下面有個git

 

config.h文件,在第一行就能夠看到當前版本,那咱們就去http://code.google.com/p/protobuf/downloads/list  github

下載版本。網絡

第二,下載下來後,咱們添加這個protobuf工程到你的項目工程中app

第三,右擊你的項目,添加該protobuf爲依賴項目,把cocos2d-x\tools\simulator\libsimulator\lib\protobuf-lite,這下面的google下面的protobuf文件夾所有刪掉,替換成你解壓後的src下面的google中的protobuf。config.h文件也替換成你的vsprojects下的config.h文件socket

第四,開始編譯--》應該是沒有問題的ide

第五,咱們要開始生成咱們的.proto文件了,怎麼弄呢?還記得先前下載下來的protobuf文件嗎?解壓後,裏面有個vsprojects 文件夾,protobuf.sln 用Vs打開這個工程編譯protobuf工程,編譯完以後,再編譯test工程,這個時候會生成protoc.exe文件,這個文件就是咱們所須要的。函數

第六,咱們開始編寫咱們的proto文件了,寫一個.bat文件,內容:

 

[cpp]  view plain  copy
 
  1. protoc.exe MsgProtocol.proto --cpp_out=./  
  2. pause  


其中:***.proto爲文件名, cpp爲生成的C++文件,還能夠生成其餘:java, python等,可是暫時不支持lua的,out後面是路徑,跟你的.proto文件是同一路徑

 

.proto文件中的內容能夠直接定義message,例如:

 

[cpp]  view plain  copy
 
  1. message Person {  
  2.     required int32 id = 1;  
  3.     required string name = 2;  
  4.     optional string emial = 3;  
  5.     optional string text = 4;  
  6.     enum MsgType {  
  7.         MsgType_None = 0;  
  8.         MsgType_ONE = 1;  
  9.         MsgType_TWO = 2;  
  10.         MsgType_THREE = 3;  
  11.         MsgType_FOUR = 4;  
  12.         MsgType_FIVE = 5;  
  13.     }  
  14.       
  15.     enum MsgStatus {  
  16.         MsgStatus_NONE = 0;  
  17.         MsgStatus_ONE  = 1;  
  18.         MsgStatus_TWO  = 2;  
  19.     }  
  20.   
  21.     optional MsgType msg = 5;  
  22.     optional MsgStatus status = 6;  
  23.       
  24. }  


第七,寫完bat,proto後,把.bat, protoc.exe, .proto文件複製到你項目目錄下面(其實,任意位置均可以,只要這三個文件保持在同一目錄就能夠),運行.bat文件後,會成成.pb.cc,.pb.h文件,這個就是你生成的文件,把這兩個文件複製到你的項目中,你就能夠隨意使用了。

 

以上是C++集成protobuf。。

 

下面來說一下Lua集成Protobuf,先去下載pbc:https://github.com/cloudwu/pbc

把這個項目下來,添加到你的項目工程中,而後編譯一下。應該是編譯沒有問題的。接下來說重要的部分:

第一:右擊的項目工程,把pbc添加爲依賴項

第二:在pbc工程裏面建立一個頭文件"pbc-lua.h"(最好放在工程的pbc目錄下),內容以下:

 

[cpp]  view plain  copy
 
  1. #ifndef PBC_LUA_H  
  2. #define PBC_LUA_H  
  3. //    
  4.   
  5. //  pbc-lua.h    
  6.   
  7. //  pbc    
  8.   
  9. //    
  10.   
  11. //  Created by ArcherPeng on 15/7/21.    
  12.   
  13. //  Copyright (c) 2015年 ztgame. All rights reserved.    
  14.   
  15. //    
  16.   
  17.   
  18.   
  19.   
  20. #if defined(_USRDLL)    
  21.   
  22. #define LUA_EXTENSIONS_DLL     __declspec(dllexport)    
  23.   
  24. #else         /* use a DLL library */    
  25.   
  26. #define LUA_EXTENSIONS_DLL    
  27.   
  28. #endif    
  29.   
  30.   
  31.   
  32. #if __cplusplus    
  33.   
  34. extern "C" {  
  35.   
  36. #endif    
  37. #include "lauxlib.h"  
  38.   
  39.   
  40.   
  41.     int LUA_EXTENSIONS_DLL luaopen_protobuf_c(lua_State *L);  
  42.   
  43.   
  44.   
  45. #if __cplusplus    
  46.   
  47. }  
  48.   
  49. #endif    
  50.   
  51.   
  52.   
  53. #endif/* pbc_pbc_lua_h */  


第三:把binding/lua/pbc-lua.c (也放在工程的pbc目錄下),代碼以下:

 

 

[cpp]  view plain  copy
 
  1. #ifdef __cplusplus    
  2.   
  3. extern "C" {    
  4.   
  5.     #endif    
  6.   
  7.     #include "lua.h"    
  8.   
  9.     #include "lualib.h"    
  10.   
  11.     #include "lauxlib.h"    
  12.   
  13.          
  14.   
  15.     #include "pbc.h"    
  16.   
  17.     #include "pbc-lua.h"//引入剛剛建立的頭文件    
  18.   
  19.          
  20.   
  21.     #ifdef __cplusplus    
  22.   
  23. }    
  24.   
  25. #endif  


第四:

 

首先要修改pbc工程的頭文件搜索路徑:

加入一條路徑:項目路徑/frameworks/cocos2d-x/external/lua/lua (這裏最好使用相對路徑,但絕對路徑也能夠)

 

第五:

添加完成後,回到AppDelegate.cpp中,引入頭文件#include"pbc/pbc/pbc-lua.h",並在boolAppDelegate::applicationDidFinishLaunching()方法中加入luaopen_protobuf_c(L);用於將protobuf的函數註冊進LUA,代碼以下:

 

[cpp]  view plain  copy
 
  1. bool AppDelegate::applicationDidFinishLaunching()    
  2.   
  3. {    
  4.   
  5.     // set default FPS    
  6.   
  7.     Director::getInstance()->setAnimationInterval(1.0 / 60.0f);    
  8.   
  9.         
  10.   
  11.     // register lua module    
  12.   
  13.     auto engine = LuaEngine::getInstance();    
  14.   
  15.     ScriptEngineManager::getInstance()->setScriptEngine(engine);    
  16.   
  17.     lua_State* L = engine->getLuaStack()->getLuaState();    
  18.   
  19.     lua_module_register(L);    
  20.   
  21.          
  22.   
  23.     luaopen_protobuf_c(L);//在lua中註冊Proto函數    
  24.   
  25.          
  26.   
  27.     register_all_packages();    
  28.   
  29.      
  30.   
  31.     LuaStack* stack = engine->getLuaStack();    
  32.   
  33.     stack->setXXTEAKeyAndSign("2dxLua", strlen("2dxLua"), "XXTEA", strlen("XXTEA"));    
  34.   
  35.          
  36.   
  37.     if (engine->executeScriptFile("src/main.lua"))    
  38.   
  39.     {    
  40.   
  41.         return false;    
  42.   
  43.     }    
  44.   
  45.          
  46.   
  47.     return true;    
  48.   
  49. }  

 

 

第六:接下來咱們要再爲LUA註冊一個函數用於讀取pb文件數據:

[cpp] view plain copy
 
  1. static int readProtobufFile(lua_State *L)    
  2.   
  3. {    
  4.   
  5.     const char *buff = luaL_checkstring(L, -1);    
  6.   
  7.     Data data = CCFileUtils::getInstance()->getDataFromFile(buff);    
  8.   
  9.     lua_pushlstring(L, (const char*)data.getBytes(), data.getSize());    
  10.   
  11.     return 1; /* number of results */    
  12.   
  13. }  
並將該函數註冊到lua中,在staticint register_all_packages()中添加以下語句:

[cpp] view plain copy
 
  1. // If you want to use packages manager to install more packages,     
  2.   
  3. // don't modify or remove this function    
  4.   
  5. static int register_all_packages()    
  6.   
  7. {    
  8.   
  9.     lua_State *L = LuaEngine::getInstance()->getLuaStack()->getLuaState();    
  10.   
  11.     luaopen_protobuf_c(L);    
  12.   
  13.          
  14.   
  15.     lua_register(L,"readProtobufFile",readProtobufFile);    
  16.   
  17.     return 0; //flag for packages manager    
  18.   
  19. }  

第七:編譯並運行,編譯經過後,遊戲運行成功!

第八:

至此,C++端設置完畢。可是並無結束,還有最後幾步。

回到遊戲項目的binding/lua目錄,找到"protobuf.lua"文件,將其複製到lua項目的src目錄下。


第九:

在LUA中Protobuf的簡單例程:

require "app/protobuf.lua" //導入你的protobuf.lua文件

 

[cpp] view plain copy
 
  1. local pbFilePath = cc.FileUtils:getInstance():fullPathForFilename("app/MsgProtocol.pb")      
  2. release_print("PB file path: "..pbFilePath)      
  3.   
  4. local buffer = readProtobufFile(pbFilePath)      
  5. protobuf.register(buffer) --注:protobuf 是由於在protobuf.lua裏面使用module(protobuf)來修改全局名字  
  6.   
  7. local stringbuffer = protobuf.encode("Person",      
  8.     {      
  9.         name = "Alice",      
  10.         id = 12345,      
  11.         phone = {      
  12.             {      
  13.                 number = "87654321"      
  14.             },      
  15.         }      
  16.     })      
  17.      
  18. local slen = string.len(stringbuffer)      
  19. local temp = ""      
  20. for i=1, slen do      
  21.     temp = temp .. string.format("0xX, ", string.byte(stringbuffer, i))      
  22. end      
  23. release_print(temp)      
  24. local result = protobuf.decode("Person", stringbuffer)      
  25. release_print("result name: "..result.name)  
  26. release_print("result name: "..result.id)  

MsgProtocol.proto的內容:

 

 

[cpp] view plain copy
 
  1. message Person {  
  2.   required string name = 1;  
  3.   required int32 id = 2;  
  4.   optional string email = 3;  
  5.   
  6.   enum PhoneType {  
  7.     MOBILE = 0;  
  8.     HOME = 1;  
  9.     WORK = 2;  
  10.   }  
  11.   
  12.   message PhoneNumber {  
  13.     required string number = 1;  
  14.     optional PhoneType type = 2 [default = HOME];  
  15.   }  
  16.   
  17.   repeated PhoneNumber phone = 4;  
  18. }  
  19.   
  20. message AddressBook {  
  21.   repeated Person person = 1;  
  22. }  
須要生成.pb文件的話,你利用前面C++的集成方法生成:protoc.exe,.bat文件生成便可
注。這裏須要生成的是pb文件,因此.bat的內容須要修改一下:
[cpp]  view plain  copy
 
  1. protoc.exe --descriptor_set_out=./MsgProtocol.pb ./MsgProtocol.proto  
MsgProtocol 爲你的pb文件名

 



最後添加到android.mk裏面,蛋疼啊。。。
 
其實很簡單的,只須要添加你的文件目錄便可,用*.cpp或者*.c來搜索,這樣實在是太方便了,省了不少事情,再也不逐個逐個的添加(參考:http://blog.csdn.net/fu_zk/article/details/12836431)
[cpp]  view plain  copy
 
  1. LOCAL_PATH := $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_MODULE := cocos2dlua_shared  
  6.   
  7. LOCAL_MODULE_FILENAME := libcocos2dlua  
  8.   
  9. FILE_LIST := hellolua/main.cpp    
  10. FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/*.cpp)    
  11. FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/lua/*.cpp)  
  12. FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/socket/*.cpp)  
  13. FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/hotUpdate/*.cpp)  
  14. FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/ide-support/*.cpp)    
  15. FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/ide-support/*.c)   
  16.   
  17. #添加    
  18. FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/pbc/binding/lua/*.c)    
  19. FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/pbc/src/*.c)    
  20.     
  21. LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)    
  22.   #你的工程目錄  
  23. LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes  
  24.   
  25. #你的工程目錄其餘自文件夾目錄  
  26. LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../Classes/pbc    
  27. LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../Classes/pbc/src    
  28.   
  29. # _COCOS_HEADER_ANDROID_BEGIN  
  30. # _COCOS_HEADER_ANDROID_END  
  31.   
  32. LOCAL_STATIC_LIBRARIES := cocos2d_lua_static  
  33. LOCAL_STATIC_LIBRARIES += cocos2d_simulator_static  
  34.   
  35. # _COCOS_LIB_ANDROID_BEGIN  
  36. # _COCOS_LIB_ANDROID_END  
  37.   
  38. include $(BUILD_SHARED_LIBRARY)  
  39.   
  40. $(call import-module,scripting/lua-bindings/proj.android)  
  41. $(call import-module,tools/simulator/libsimulator/proj.android)  
  42.   
  43. # _COCOS_LIB_IMPORT_ANDROID_BEGIN  
  44. # _COCOS_LIB_IMPORT_ANDROID_END  
相關文章
相關標籤/搜索