1. 程式人生 > >cocos2dx-lua呼叫C++

cocos2dx-lua呼叫C++

文參考:https://www.cnblogs.com/xiaonanxia/p/4987856.html

上面的文章是IOS版教程,用4部分說明原理,1部分說操作步驟。

這裡用window VS2013環境說操作步驟。

 

第五層:使用Cocos2d-x的方式來將C++類註冊進Lua環境

接下來說怎麼用bindings-generator指令碼:

1、寫自己的C++類,按照Cocos2d-x的規矩,繼承cocos2d::Ref類,以便使用Cocos2d-x的記憶體回收機制。當然不這麼幹也行,但是不推薦,不然在Lua環境下物件的釋放狠麻煩。  

2、編寫一個.ini檔案,讓bindings-generator可以根據這個配置檔案知道C++類該怎麼暴露出來

3、修改bindings-generator指令碼,讓它去讀取這個.ini檔案

4、執行bindings-generator指令碼,生成橋接C++類方法

5、用VS將自定義的C++類和生成的橋接檔案加入工程,不然編譯不到

6、修改AppDelegate.cpp,執行橋接方法,自定義的C++類就註冊進Lua環境裡了

 

看著步驟挺多,其實都狠簡單。下面一步一步來。

   

首先是自定義的C++類。我習慣將檔案儲存在frameworks/runtime-src/Classes/目錄下:

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);
};

  

frameworks/runtime-src/Classes/MyClass.cpp
#include "MyClass.h"
int MyClass::foo(int
i) { return i + 100; }

然後編寫.ini檔案。在frameworks/cocos2d-x/tools/lua/目錄下能看到genbindings.py指令碼和一大堆.ini檔案,這些就是bindings-generator的實際執行環境了。隨便找一個內容比較少的.ini檔案,複製一份,重新命名為MyClass.ini。大部分內容都可以湊合不需要改,這裡僅列出必須要改的重要部分:  

frameworks/cocos2d-x/tools/tolua/MyClass.ini  

[MyClass]
prefix           = MyClass
target_namespace = my
headers          = %(cocosdir)s/../runtime-src/Classes/MyClass.h
classes          = MyClass

也即在MyClass.ini中指定MyClass.h檔案的位置,指定要暴露出來的類,指定註冊進Lua環境的模組名。  

注意:這個地方我踩了個坑。如果.ini配置檔案中存在macro_judgement = ...巨集定義,要特別小心,我第一次是從cocos2dx_controller.ini檔案複製來的,結果沒注意macro_judgement,導致生成的橋接類檔案加入了不該加入的巨集,只在iOS和Android平臺上才起作用,對Mac平臺無效,這個要特別注意。

  

然後修改genbindings.py檔案129行附近,將MyClass.ini檔案加進去:

frameworks/cocos2d-x/tools/tolua/genbindings.py  

cmd_args = {'cocos2dx.ini' : ('cocos2d-x', 'lua_cocos2dx_auto'), \
            'MyClass.ini' : ('MyClass', 'lua_MyClass_auto'), \
            ...

每次執行genbindings.py指令碼時間都挺長的,因為它要重新處理一遍所有的.ini檔案,建議大膽修改指令碼檔案,靈活處理,讓它每次只處理需要的.ini檔案就可以了,比如像這個樣子:

 

至此,生成橋接檔案的準備工作就做好了,執行genbindings.py指令碼:(執行命令需要的環境在下面)  

python genbindings.py

執行這個命令需要的條件在frameworks\cocos2d-x\tools\tolua目錄下,有個README.mdown的檔案說明,裡面有不同系統的安裝方法。

我用的是python-2.7.14,下載地址:http://www.python.org/ftp/python/2.7.14/python-2.7.14.msi

注意:這個README裡,window版給的下載地址是過期的,所以用python的pip功能下載對應外掛

開啟cmd,cd C:\Python27\Scripts(你自己的安裝目錄)

pip install PyYAML

pip install Cheetah

上面兩行是安裝適合版本的外掛。   成功執行genbindings.py指令碼後,會在frameworks/cocos2d-x/cocos/scripting/lua-bindings/auto/目錄下看到新生成的橋接C++檔案:  

把這兩個檔案新增到VS libluacocos2d工程中auto目錄下:

 

 在frameworks/cocos2d-x/cocos/scripting/lua-bindings/auto/目錄下觀察一下生成的C++橋接檔案lua_MyClass_auto.cpp,裡面的註冊函式名字為register_all_MyClass(),這就是將MyClass類註冊進Lua環境的關鍵函式:

生成的橋接檔案內容

 

編輯frameworks/runtime-src/Classes/AppDelegate.cpp檔案,首先在檔案頭加入對lua_MyClass_auto.hpp檔案的引用:

AppDelegate.cpp檔案的頭加入對lua_MyClass_auto.hpp檔案的引用

 

然後在正確的程式碼位置加入對register_all_MyClass函式的呼叫:      

  

修改AppDelegate.cpp檔案,將MyClass類註冊進Lua環境

  這其中還有一個小坑,由於lua_MyClass_auto.cpp檔案要引用MyClass.h檔案,而這倆檔案分屬於不同的子專案,互相不認識標頭檔案的搜尋路徑,因此需要手工修改一下libluacocos2d子專案的包含路徑 配置。在 屬性-配置屬性VC++目錄-包含目錄,這裡加上MyClass.h的路徑: ..\..\..\..\..\runtime-src\Classes

最後,就可以F7重新編譯整個專案了,不出意外的話編譯一定是成功的。

 修改main.lua檔案中,嘗試呼叫一下MyClass類:

local test = my.MyClass:create()
print("lua bind: " .. test:foo(99))

然後執行程式,下面是見證奇蹟的時刻~~~~!

程式終於正確執行了

 

至此,就徹底搞清楚應該怎樣在Cocos2d-x專案裡繫結一個C函式或者C++類到Lua環境中了,感興趣的話可以再進一步深入研究Lua內部metatable的運作原理、類物件的生成與釋放、以及垃圾回收。我自己也是剛接觸Cocos2d-x不到幾年,理解不深,以上難免會有用詞不當或理解錯誤的地方,如有錯誤請多包涵。