http://blog.csdn.net/ganpengjin1/article/details/50964961java
Cocos2dx 裏面在網絡遊戲通訊這一塊通常咱們都會採用protobuf來進行通訊,cocos引擎沒有集成C++的protobuf,那咱們只能本身來集成了。由於protobuf有不少版本,那麼咱們怎麼去下載與引擎中想對應的protobuf版本呢。python
他在android
- 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文件,內容:
- protoc.exe MsgProtocol.proto --cpp_out=./
- pause
其中:***.proto爲文件名, cpp爲生成的C++文件,還能夠生成其餘:java, python等,可是暫時不支持lua的,out後面是路徑,跟你的.proto文件是同一路徑
.proto文件中的內容能夠直接定義message,例如:
- message Person {
- required int32 id = 1;
- required string name = 2;
- optional string emial = 3;
- optional string text = 4;
- enum MsgType {
- MsgType_None = 0;
- MsgType_ONE = 1;
- MsgType_TWO = 2;
- MsgType_THREE = 3;
- MsgType_FOUR = 4;
- MsgType_FIVE = 5;
- }
-
- enum MsgStatus {
- MsgStatus_NONE = 0;
- MsgStatus_ONE = 1;
- MsgStatus_TWO = 2;
- }
-
- optional MsgType msg = 5;
- optional MsgStatus status = 6;
-
- }
第七,寫完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目錄下),內容以下:
- #ifndef PBC_LUA_H
- #define PBC_LUA_H
-
-
-
-
-
-
-
-
-
-
- #if defined(_USRDLL)
-
- #define LUA_EXTENSIONS_DLL __declspec(dllexport)
-
- #else /* use a DLL library */
-
- #define LUA_EXTENSIONS_DLL
-
- #endif
-
-
-
- #if __cplusplus
-
- extern "C" {
-
- #endif
- #include "lauxlib.h"
-
-
-
- int LUA_EXTENSIONS_DLL luaopen_protobuf_c(lua_State *L);
-
-
-
- #if __cplusplus
-
- }
-
- #endif
-
-
-
- #endif/* pbc_pbc_lua_h */
第三:把binding/lua/pbc-lua.c (也放在工程的pbc目錄下),代碼以下:
- #ifdef __cplusplus
-
- extern "C" {
-
- #endif
-
- #include "lua.h"
-
- #include "lualib.h"
-
- #include "lauxlib.h"
-
-
-
- #include "pbc.h"
-
- #include "pbc-lua.h"//引入剛剛建立的頭文件
-
-
-
- #ifdef __cplusplus
-
- }
-
- #endif
第四:
首先要修改pbc工程的頭文件搜索路徑:
加入一條路徑:項目路徑/frameworks/cocos2d-x/external/lua/lua (這裏最好使用相對路徑,但絕對路徑也能夠)
第五:
添加完成後,回到AppDelegate.cpp中,引入頭文件#include"pbc/pbc/pbc-lua.h",並在boolAppDelegate::applicationDidFinishLaunching()方法中加入luaopen_protobuf_c(L);用於將protobuf的函數註冊進LUA,代碼以下:
- bool AppDelegate::applicationDidFinishLaunching()
-
- {
-
-
-
- Director::getInstance()->setAnimationInterval(1.0 / 60.0f);
-
-
-
-
-
- auto engine = LuaEngine::getInstance();
-
- ScriptEngineManager::getInstance()->setScriptEngine(engine);
-
- lua_State* L = engine->getLuaStack()->getLuaState();
-
- lua_module_register(L);
-
-
-
- luaopen_protobuf_c(L);
-
-
-
- register_all_packages();
-
-
-
- LuaStack* stack = engine->getLuaStack();
-
- stack->setXXTEAKeyAndSign("2dxLua", strlen("2dxLua"), "XXTEA", strlen("XXTEA"));
-
-
-
- if (engine->executeScriptFile("src/main.lua"))
-
- {
-
- return false;
-
- }
-
-
-
- return true;
-
- }
第六:接下來咱們要再爲LUA註冊一個函數用於讀取pb文件數據:
- static int readProtobufFile(lua_State *L)
-
- {
-
- const char *buff = luaL_checkstring(L, -1);
-
- Data data = CCFileUtils::getInstance()->getDataFromFile(buff);
-
- lua_pushlstring(L, (const char*)data.getBytes(), data.getSize());
-
- return 1;
-
- }
並將該函數註冊到lua中,在staticint register_all_packages()中添加以下語句:
-
-
- static int register_all_packages()
-
- {
-
- lua_State *L = LuaEngine::getInstance()->getLuaStack()->getLuaState();
-
- luaopen_protobuf_c(L);
-
-
-
- lua_register(L,"readProtobufFile",readProtobufFile);
-
- return 0;
-
- }
第七:編譯並運行,編譯經過後,遊戲運行成功!
第八:
至此,C++端設置完畢。可是並無結束,還有最後幾步。
回到遊戲項目的binding/lua目錄,找到"protobuf.lua"文件,將其複製到lua項目的src目錄下。
第九:
在LUA中Protobuf的簡單例程:
require "app/protobuf.lua" //導入你的protobuf.lua文件
- local pbFilePath = cc.FileUtils:getInstance():fullPathForFilename("app/MsgProtocol.pb")
- release_print("PB file path: "..pbFilePath)
-
- local buffer = readProtobufFile(pbFilePath)
- protobuf.register(buffer) --注:protobuf 是由於在protobuf.lua裏面使用module(protobuf)來修改全局名字
-
- local stringbuffer = protobuf.encode("Person",
- {
- name = "Alice",
- id = 12345,
- phone = {
- {
- number = "87654321"
- },
- }
- })
-
- local slen = string.len(stringbuffer)
- local temp = ""
- for i=1, slen do
- temp = temp .. string.format("0xX, ", string.byte(stringbuffer, i))
- end
- release_print(temp)
- local result = protobuf.decode("Person", stringbuffer)
- release_print("result name: "..result.name)
- release_print("result name: "..result.id)
MsgProtocol.proto的內容:
- message Person {
- required string name = 1;
- required int32 id = 2;
- optional string email = 3;
-
- enum PhoneType {
- MOBILE = 0;
- HOME = 1;
- WORK = 2;
- }
-
- message PhoneNumber {
- required string number = 1;
- optional PhoneType type = 2 [default = HOME];
- }
-
- repeated PhoneNumber phone = 4;
- }
-
- message AddressBook {
- repeated Person person = 1;
- }
須要生成.pb文件的話,你利用前面C++的集成方法生成:protoc.exe,.bat文件生成便可
注。這裏須要生成的是pb文件,因此.bat的內容須要修改一下:
- protoc.exe --descriptor_set_out=./MsgProtocol.pb ./MsgProtocol.proto
MsgProtocol 爲你的pb文件名
最後添加到android.mk裏面,蛋疼啊。。。
其實很簡單的,只須要添加你的文件目錄便可,用*.cpp或者*.c來搜索,這樣實在是太方便了,省了不少事情,再也不逐個逐個的添加(參考:http://blog.csdn.net/fu_zk/article/details/12836431)
- LOCAL_PATH := $(call my-dir)
-
- include $(CLEAR_VARS)
-
- LOCAL_MODULE := cocos2dlua_shared
-
- LOCAL_MODULE_FILENAME := libcocos2dlua
-
- FILE_LIST := hellolua/main.cpp
- FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/*.cpp)
- FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/lua/*.cpp)
- FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/socket/*.cpp)
- FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/hotUpdate/*.cpp)
- FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/ide-support/*.cpp)
- FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/ide-support/*.c)
-
- #添加
- FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/pbc/binding/lua/*.c)
- FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/pbc/src/*.c)
-
- LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
- #你的工程目錄
- LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes
-
- #你的工程目錄其餘自文件夾目錄
- LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../Classes/pbc
- LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../Classes/pbc/src
-
- # _COCOS_HEADER_ANDROID_BEGIN
- # _COCOS_HEADER_ANDROID_END
-
- LOCAL_STATIC_LIBRARIES := cocos2d_lua_static
- LOCAL_STATIC_LIBRARIES += cocos2d_simulator_static
-
- # _COCOS_LIB_ANDROID_BEGIN
- # _COCOS_LIB_ANDROID_END
-
- include $(BUILD_SHARED_LIBRARY)
-
- $(call import-module,scripting/lua-bindings/proj.android)
- $(call import-module,tools/simulator/libsimulator/proj.android)
-
- # _COCOS_LIB_IMPORT_ANDROID_BEGIN
- # _COCOS_LIB_IMPORT_ANDROID_END