參考:http://www.cocos2d-x.org/docs/manual/code-ide/binding-custom-class-to-lua/enjavascript
// // HNLuaTest.h // cocos2d_libs // // Created by Eleven Chen on 14-8-5. // // #ifndef __cocos2d_libs__HNLuaTest__ #define __cocos2d_libs__HNLuaTest__ #include "cocos2d.h" #include <string> class Test : public cocos2d::Ref { public: static std::string helloMsg(); static Test* create(); bool init(); static cocos2d::Vec2 left(); }; #endif /* defined(__cocos2d_libs__HNLuaTest__) */
// // HNLuaTest.cpp // cocos2d_libs // // Created by Eleven Chen on 14-8-5. // // #include "HNLuaTest.h" using namespace cocos2d; std::string Test::helloMsg() { return "Hello from HNLuaTest::helloMsg()"; } Test* Test::create() { return new Test(); } bool Test::init() { return true; } Vec2 Test::left() { return Vec2(0, 0); }
進入到tolua目錄:$(PROJECT_ROOT)/frameworks/cocos2d-x/tools/toluajava
在以前先看看README文件,並安裝好環境。android
README文件中提到必需要用android ndk r9b來編譯,由於編譯的時候用到了C++ std 4.7的頭文件,而r9b包含了4.7,我用的是r9d,只有4.6和4.8。我把*.ini文件裏面的4.7改爲4.8來編譯。 ios
新建一個cocos2dx_custom.ini文件,而後從其餘文件裏面copy一份代碼過來修改,代碼裏面每個設置都有詳細的註釋。c++
[cocos2dx_custom] # the prefix to be added to the generated functions. You might or might not use this in your own # templates prefix = cocos2dx_custom # 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 = cc # the native namespace in which this module locates, this parameter is used for avoid conflict of the same class name in different modules, as "cocos2d::Label" <-> "cocos2d::ui::Label". cpp_namespace = android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/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/editor-support -I%(cocosdir)s/cocos/platform/android cocos_flags = -DANDROID 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/cocos/my/HNLuaTest.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 = Test.* # 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 = Test # base classes which will be skipped when their sub-classes found them. base_classes_to_skip = # 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
爲了方便,每次綁定時不須要生成cocos2d-x的綁定代碼,新建一個genbindings_custom.py
文件,而後複製genbindings.py
的代碼過來,把下面的地方:express
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'), \ 'custom.ini': ('custom', 'lua_custom_auto'), \ 'cocos2dx_custom.ini' : ('cocos2dx_custom', 'lua_cocos2dx_custom_auto'), \ }
改成xcode
cmd_args = {'cocos2dx_custom.ini' : ('cocos2dx_custom', 'lua_cocos2dx_custom_auto'), \ }
./genbindings_custom.py
生成的代碼在 cocos/scripting/lua-bindings/auto
裏面 app
my
my
文件夾中添加Android.mk文件,以下內容LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := cocos_custom_static LOCAL_MODULE_FILENAME := libmy LOCAL_SRC_FILES := \ HNLuaTest.cpp LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \ $(LOCAL_PATH)./ LOCAL_C_INCLUDES := $(LOCAL_PATH) \ $(LOCAL_PATH)./ LOCAL_CFLAGS += -Wno-psabi LOCAL_EXPORT_CFLAGS += -Wno-psabi LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static include $(BUILD_STATIC_LIBRARY) $(call import-module,.)
LOCAL_SRC_FILES := manual/CCLuaBridge.cpp \ #省略 auto/lua_cocos2dx_custom_auto.cpp \ ../../../external/lua/tolua/tolua_event.c \ #省略
修改AppDelegate.cpp
ide
//register custom function //LuaStack* stack = engine->getLuaStack(); //register_custom_function(stack->getLuaState()); LuaStack *stack = engine->getLuaStack(); auto L = stack->getLuaState(); if (L) { lua_getglobal(L, "_G"); register_all_cocos2dx_custom(L); lua_settop(L, 0); } #if (COCOS2D_DEBUG>0) if (startRuntime()) return true; #endif engine->executeScriptFile(ConfigParser::getInstance()->getEntryFile().c_str()); return true;
這裏不能按照本來代碼註釋的方法那樣作,那樣會出錯。函數
並且都是tolua_module
這個函數裏面的 lua_rawget(L,-2);
這一行出錯。
緣由是:
LuaEngine初始化的時候會運行3個lua文件,把stack給清空了。
在tolua_module
函數中,lua_pushstring(L,name);
後,棧只有一個元素,因此lua_rawget(L,-2);
就會出錯。
只須要把_G
放到棧中,再運行register_all_cocos2dx_custom(L);
,若是模塊不在_G
中,就添加到_G
中,就能夠全局訪問了。
-- test custom local msg = cc.Test:helloMsg() print(msg)
輸出
打開:cocos2d-x/tools/bindings-generator/targets/lua/conversions.yaml文件 在ns_map添加本身的命名空間:
ns_map: "cocos2d::extension::": "cc." "cocos2d::ui::": "ccui." "cocos2d::": "cc." "spine::": "sp." "cocostudio::": "ccs." "cocosbuilder::": "cc." "CocosDenshion::": "cc." # 我本身的命名空間 "hunuo::": "hn."