首先,自定义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/tolua/目录下能看到genbindings.py脚本和一大堆.ini文件,这些就是bindings-generator的实际执行环境了。随便找一个内容比较少的.ini文件,复制一份然后修改内容如下,重新命名为MyClass.ini。
frameworks/cocos2d-x/tools/tolua/MyClass.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 = my
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/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/../runtime-src/Classes/MyClass.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 =MyClass
# 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 =
# 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
如果之前做过绑定成功,那么则环境已经ok没问题,再次操作如果出现绑定失败的话,通常绑定失败都是ini修改的原因.
需要小心,哈,这里涉及的东西还是比较多的.
这里仅列出必须要改的重要部分:
[MyClass]
prefix = MyClass
target_namespace = my
headers = %(cocosdir)s/../runtime-src/Classes/MyClass.h
classes = MyClass
headers, classes, skip, abstract_class等内容相应的地方进行修改。
然后复制并修改genbindings.py文件
为了方便,只生成新的绑定代码,复制genbindings.py并修改文件命名为genbindings_custom.py
,然后修改文件129行附近,把下面的地方修改(从而将MyClass.ini文件加进去):
原文内容:
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'), \
}
frameworks/cocos2d-x/tools/tolua/genbindings_custom.py该部分修改后内容:
cmd_args = {'MyClass.ini' : ('MyClass', 'lua_MyClass_auto'), \
}
打开终端运行genbindings_custom.py
注意这里需要先cd到该目录,然后才可以再用命令./genbindings_custom.py生成桥接绑定的文件.
成功执行./genbindings_custom.py脚本后,
会在frameworks/cocos2d-x/cocos/scripting/lua-bindings/auto/目录下看到新生成的文件:
lua_MyClass_auto.hpp和lua_MyClass_auto.cpp
把以上两个文件,添加到cocos2dx项目中,注意是添加到cocos2d_lua_bindings.xcodeproj的auto中.
并且设置lua_MyClass_auto.cpp,头文件引用的MyClass.h的搜索路径,或者使用绝对路径
在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文件的引用:
#include "lua_MyClass_auto.hpp"
然后在正确的代码位置加入对register_all_MyClass函数的调用:例如在AppDelegate中添加
bool AppDelegate::applicationDidFinishLaunching()
{
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLView::createWithRect("game", Rect(0,0,900,640));
director->setOpenGLView(glview);
}
glview->setDesignResolutionSize(480, 320, ResolutionPolicy::NO_BORDER);
// turn on display FPS
director->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);
auto engine = LuaEngine::getInstance();
ScriptEngineManager::getInstance()->setScriptEngine(engine);
// 添加以下5句 实现Lua绑定C++
LuaStack *stack=engine->getLuaStack();
lua_State *L = stack->getLuaState();
lua_getglobal(L, "_G");
register_all_MyClass(L);
lua_settop(L, 0);
if (engine->executeScriptFile("src/main.lua")) {
return false;
}
return true;
}
最后 修改main.lua文件中,尝试调用一下MyClass类:
local test = my.MyClass:create()
print(
"lua bind!!!!!!!!!!!!!! "
.. test:foo(99))
参考资料:
http://cn.cocos2d-x.org/tutorial/show?id=1295
http://blog.csdn.net/xuxhing/article/details/34070685
http://my.oschina.net/skyhacker2/blog/298397