cocos2dx tolua ++ 使用 常見得錯誤

步驟:
1、安裝必要的庫和工具包,以及配置相關環境變量,請按照cocos2d-x-3.0rc0\tools\tolua\README.mdown說得去做
(注意:儘量用README.mdown說的同一個ndk版本(最好用9系列),不然需要改東西NDK各個版本鏈接
2、寫c++類(我測試用的是cocos2d-x-3.0rc0\tests\lua-empty-test\project\Classes\自定義.cpp)

注意:你寫的方法一定要public,不然不會編譯到lua,會報錯attempt to call method ‘方法名’ (a nil value)
注意:在xcode寫c++類的時候,如果包含路徑一定要寫完,xcode不會報錯,但是tolua是就會又問題了!(TranslationUnitLoadError: Error parsing translation unit.)

注意:如果自定義的類別裏有自行定義的 namespace 時,跑 .bat 後看 output log 的最後一行會發現這樣的錯誤:

Exception: The namespace (Evo::TalkWidget) conversion wasn’t set in ‘ns_map’ section of the conversions.yaml

去找一下 conversions.yaml 這個檔,位置應該在 /tools/bindings-generator/targets/lua 底下,直接用文字編輯器打開來看。

把自訂的 namespace 加到 ns_map 的變數中,那個 .ini 裏的 cpp_namespace 作用

要加的內容如下:


ns_map:
“cocos2d::extension::”: “cc.”
“cocos2d::ui::”: “ccui.”
“cocos2d::”: “cc.”
“spine::”: “sp.”
“cocostudio::”: “ccs.”
“cocosbuilder::”: “cc.”
“CocosDenshion::”: “cc.”
3、寫一個生成的python腳本,你不會寫,沒關係,我們會照着葫蘆畫瓢
1)進入目錄cocos2d-x-3.0rc0\tools\tolua,複製一份genbindings.py,命名爲genbindings_myclass.py
2)把生成目錄制定到咱工程裏去,打開genbindings_myclass.py把

output_dir = '%s/cocos/scripting/lua-bindings/auto' % project_root

改成

output_dir = '%s/tests/lua-empty-test/project/Classes/auto' % project_root

3)修改命令參數,把

cmd_args = {'cocos2dx.ini' : ('cocos2d-x', 'lua_cocos2dx_auto'), \
                    'cocos2dx_extension.ini' : ('cocos2dx_extension', 'lua_cocos2dx_extension_auto'), \
                    'cocos2dx_ui.ini' : ('cocos2dx_ui', 'lua_cocos2dx_ui_auto'), \
                    'cocos2dx_studio.ini' : ('cocos2dx_studio', 'lua_cocos2dx_studio_auto'), \
                    'cocos2dx_spine.ini' : ('cocos2dx_spine', 'lua_cocos2dx_spine_auto'), \
                    'cocos2dx_physics.ini' : ('cocos2dx_physics', 'lua_cocos2dx_physics_auto'), \
                    }
改成
cmd_args = {'myclass.ini' : ('myclass', 'lua_myclass_auto') }
4)這時你可能問myclass.ini在哪啊,我們下來就寫這個文件。原理一樣,我還是照着葫蘆畫瓢,拿cocos2dx_spine.ini改的。
[myclass]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = myclass

# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace =

android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include
android_flags = -D_SIZE_T_DEFINED_

clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
clang_flags = -nostdinc -x c++ -std=c++11

cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/2d -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/ui -I%(cocosdir)s/cocos/physics -I%(cocosdir)s/cocos/2d/platform -I%(cocosdir)s/cocos/2d/platform/android -I%(cocosdir)s/cocos/math/kazmath -I%(cocosdir)s/extensions -I%(cocosdir)s/external -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s

cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT

cxxgenerator_headers =

# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s

# what headers to parse
headers = %(cocosdir)s/tests/lua-empty-test/project/Classes/HelloWorldScene.h

# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = HelloWorld

# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.

skip =

rename_functions =

rename_classes =

# for all class names, should we remove something when registering in the target VM?
remove_prefix =

# classes for which there will be no "parent" lookup
classes_have_no_parents =

# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip = Ref ProcessBase

# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes =

# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = no
改的時候要注意這些行
[myclass]
prefix = myclass
target_namespace =
headers = %(cocosdir)s/tests/lua-empty-test/project/Classes/HelloWorldScene.h
classes = HelloWorld
skip =
abstract_classes =

4、下面要自動生成代碼了,打開命令行工具,cd到cocos2d-x-3.0rc0\tools\tolua下,敲入

python genbindings_myclass.py

回車運行。如果前面沒問題的話你會在cocos2d-x-3.0rc0\tests\lua-empty-test\project\Classes多了一個文件夾auto,然後把裏面生成lua_myclass_auto.cpp和lua_myclass_auto.hpp加入拽如工程

5、把我們生成的個module在腳本引擎初始化的時候加入lua。
編輯AppDelegate.cpp,包含lua_myclass_auto.hpp頭文件,在

LuaEngine* engine = LuaEngine::getInstance();

後面加入

register_all_myclass(engine->getLuaStack()->getLuaState());

6、編譯運行。這樣HelloWorld這個類就被導出到lua了。

最後調用

 local hello = HelloWorld:create()
    local sceneGame = cc.Scene:create()
    sceneGame:addChild(hello)
    cc.Director:getInstance():runWithScene(sceneGame)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章