1. 程式人生 > >[Cocos2dx] C++自定義類繫結到Lua

[Cocos2dx] C++自定義類繫結到Lua

Cocos2dx通過工程裡面的tools/toLua工具生成註冊C++函式到lua的函式cpp檔案

 bindings-generator指令碼的工作機制

  1.  不用編寫.pkg和.h檔案了,直接定義一個ini檔案,註冊到Lua環境裡的模組名是什麼,就行了。
  2.  摸清了toLua++工具的生成方法,改由Python指令碼動態分析C++類,自動生成橋接的.h和.cpp程式碼,不呼叫tolua++命令了
  3. 雖然不再呼叫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 \

Cocos2d-x 3.1 Lua Binding