[Cocos2dx] C++自定義類繫結到Lua
Cocos2dx通過工程裡面的tools/toLua工具生成註冊C++函式到lua的函式cpp檔案
bindings-generator指令碼的工作機制
- 不用編寫.pkg和.h檔案了,直接定義一個ini檔案,註冊到Lua環境裡的模組名是什麼,就行了。
- 摸清了toLua++工具的生成方法,改由Python指令碼動態分析C++類,自動生成橋接的.h和.cpp程式碼,不呼叫tolua++命令了
- 雖然不再呼叫tolua++命令了,但是底層仍然使用toLua++的庫函式,比如tolua_function,bindings-generator指令碼生成的程式碼就跟使用toLua++工具生成的幾乎一樣
bindings-generator步驟
0.寫自己的C++類,按照cocos2d-x的規矩,繼承cocos2d::Ref類,以便使用cocos2d-x的記憶體回收機制。當然不這麼幹也行,但是不推薦,不然在Lua環境下物件的釋放狠麻煩。首先是自定義的C++類。通常將檔案儲存在frameworks/runtime-src/Classes/目錄下:
//MyClass.h檔案 #include "cocos2d.h" using namespace cocos2d; class MyClass : public Ref { public: MyClass() {}; ~MyClass() {}; bool init() { return true; }; CREATE_FUNC(MyClass); int foo(int i); }; //MyClass.cpp檔案 #include "MyClass.h" int MyClass::foo(int i) { return i + 100; }
1.按照官方提供的文件(\tools\tolua\ README.mdown)安裝相應軟體包
2.編寫自已的指令碼檔案,拷貝\tools\tolua\genbindings.py, myClass.py修改如下地方
3、編寫自已的配置檔案,拷貝\tools\tolua\cocos2dx_spine.ini,讓bindings-generator可以根據這個配置檔案知道C++類該怎麼暴露出來,myClass.ini修改如下地方
•[title]:要配置將被使用的工具/ tolua的/ gengindings.py指令碼的稱號。一般來說,標題可以是檔名。
•prefix:要配置一個函式名的字首,通常,我們還可以使用檔名作為字首。關係到lua函式開頭的名字,如prefix=cocos2dx,那麼生成的程式碼就是以lua_cocos2dx開頭
•target_namespace:要配置在指令碼層模組的名字。在這裡,我們使用cc作為模組名,當你想在指令碼層REF的名稱,您必須將一個名為字首,CC在名稱的前面。例如,CustomClass可以參考作為cc.CustomClass。target_namespace=custom,那麼在lua中呼叫就是以 custom. 開頭(但這個引數好像控制不到,真正能控制的是在C++裡面是否有custom的名稱空間)
這裡有兩點要注意的
如果有自定義的名稱空間,cocos2dx主目錄的tools資料夾下bindings-generator\targets\lua下的conversions.yaml(js的是bindings-generator\targets\spidermonkey下的conversions.yaml)新增自己的名稱空間:
ns_map:
"cocos2d::extension::": "cc."
"cocos2d::ui::": "ccui."
"cocos2d::": "cc."
"spine::": "sp."
"cocostudio::": "ccs."
"cocosbuilder::": "cc."
"CocosDenshion::": "cc."
"ccmy::": "ccmy."
這個檔案貌似是一些替換操作配置(就是在生成C++檔案中替換掉所設定的的字串),自己研究一下就知道了。
•headers:要配置所有需要解析的標頭檔案和%(cocosdir)s是的Cocos2d-x的引擎的根路徑。
•classes:要配置所有繫結所需的類。在這裡,它支援正則表示式。因此,我們可以設定MyCustomClass。*在這裡,用於查詢多個特定的用法,你可以對照到tools/tolua/cocos2dx.ini。
4、終端進入\tools\tolua, 執行剛修改的角本./genbindings_custom.py,成功後在output_dir指定目錄會生成lua_xxx_auto.hpp,lua_xxx_auto.cpp等檔案
5、把生成的檔案新增至專案中,編輯AppDelegate.cpp檔案,
a.包含lua_xxx_auto.hpp檔案
b.在函式applicationDidFinishLaunching()中的函式register_all_packages(L);中新增lua_xxx_auto.hpp檔案的函式register_xxx(L);
6.編寫lua指令碼呼叫
function myadd(x, y)
-- 自定義
local test = ccmy.MyClass:create()
print("lua bind: " .. test:foo(99))
return x + y
end
7.如果C++類定義了namespace,則需要修改frameworks/cocos2d-x/tools/bindings-generator/targets/lua/conversions.yaml檔案,定義namespace與Lua之間的對映關係,否則會報conversion wasn't set錯誤:
8.因為建立之後,編譯成apk時,需要找到對應的檔案,需要在mk檔案新增 不然編譯的時候提示 " error: undefined reference to register_all_xxx" 未定義
#自己的android工程目錄下jni/Android.mk檔案新增
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/xxx.cpp \