【自己主动绑定】
參考:http://my.oschina.net/skyhacker2/blog/298397
主要是通过引擎自带的tools/tolua,主要过程例如以下:
1.编写好要导出的c++类。假设是libcocos2d里加入,须要加入导出标记:class CC_DLL Test
2.到tolua文件夹依据README.mdown配置好环境:
* Make sure that you have installed `android-ndk-r9b`. * Download python2.7.3 (32bit) from (http://www.python.org/ftp/python/2.7.3/python-2.7.3.msi). * Add the installed path of python (e.g. C:Python27) to windows environment variable named 'PATH'. * Download pyyaml from http://pyyaml.org/download/pyyaml/PyYAML-3.10.win32-py2.7.exe and install it. * Download pyCheetah from https://raw.github.com/dumganhar/my_old_cocos2d-x_backup/download/downloads/Cheetah.zip, unzip it to "C:Python27Libsite-packages" * Set environment variables (`NDK_ROOT`) * Go to "cocos2d-x/tools/tolua" folder, and run "genbindings.py". The generated codes will be under "cocosscriptingauto-generatedjs-bindings".
3.创建一个ini文件,比方cocos2dx_custom.ini,參照其它的ini自己做一些改动:
# 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 # what headers to parse headers = %(cocosdir)s/cocos/for_lua/Test.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.* skip = # classes for which there will be no "parent" lookup classes_have_no_parents = Test abstract_classes =4.拷贝一份genbindings_custom.py。改动cmd_args:
cmd_args = {'cocos2dx_custom.ini' : ('cocos2dx_custom', 'lua_cocos2dx_custom_auto'), }5.执行genbindings_custom.py会生成xx_auto.h/cpp到cocosscriptinglua-bindingsauto文件夹,然后你加入到引擎的libluacocos2dproject去
6.要在lua中使用,还在启动时注冊。如今3.7的版本号里AppDelegate::applicationDidFinishLaunching会调用lua_module_register,所以:
#include "lua_cocos2dx_custom_auto.hpp" #include "fun.h" int lua_module_register(lua_State* L) { register_cocosdenshion_module(L); register_all_cocos2dx_custom(L); register_foo(L); return 1; }7.然后你就能够在lua里使用了:
-- test custom local msg = cc.Test:helloMsg() print(msg)
【手动绑定】
參考:http://www.tairan.com/archives/5493
1.创建c++类(fun.h):
#pragma once #include <iostream> #include <sstream> extern "C" { #include <lua.h> #include <lauxlib.h> #include <lualib.h> } class Foo { public: Foo(const std::string & name) : name(name) { std::cout << "Foo is born" << std::endl; } std::string Add(int a, int b) { std::stringstream ss; ss << name << ": " << a << " + " << b << " = " << (a + b); return ss.str(); } ~Foo() { std::cout << "Foo is gone" << std::endl; } private: std::string name; }; void register_foo(lua_State *L);2.导出到lua(fun.cpp):
#include "fun.h" int l_Foo_constructor(lua_State *L) { const char *name = luaL_checkstring(L, 1); Foo **udata = (Foo**)lua_newuserdata(L, sizeof(Foo*)); *udata = new Foo(name); luaL_getmetatable(L, "luaL_Foo"); // stack: // -1 metatable "luaL_Foo" // -2 userdata // -3 string param lua_setmetatable(L, -2); return 1; } Foo* l_CheckFoo(lua_State *L, int n) { return *(Foo**)luaL_checkudata(L, n, "luaL_Foo"); } int l_Foo_Add(lua_State *L) { Foo *foo = l_CheckFoo(L, 1); int a = luaL_checknumber(L, 2); int b = luaL_checknumber(L, 3); std::string s = foo->Add(a, b); lua_pushstring(L, s.c_str()); // stack: // -1 result string // -2 metatable "luaL_Foo" // -3 userdata // -4 string param return 1; } int l_Foo_destructor(lua_State *L) { Foo *foo = l_CheckFoo(L, 1); delete foo; return 0; } void register_foo(lua_State *L) { luaL_Reg sFooRefs[] = { { "new", l_Foo_constructor }, { "add", l_Foo_Add }, { "__gc", l_Foo_destructor }, { NULL, NULL } }; luaL_newmetatable(L, "luaL_Foo"); luaL_register(L, NULL, sFooRefs); lua_pushvalue(L, -1); // stack: // -1: metatable "luaL_Foo" // -2: metatable "luaL_Foo" // this pops the stack lua_setfield(L, -1, "__index"); lua_setglobal(L, "Foo"); }3.启动时注冊
4.在lua中使用:
function Foo:speak() print("hello, i am a Foo") end local foo = Foo.new("adfan") local m = foo:add(3, 4) print(m) foo:speak() Foo.add_ = Foo.add function Foo:add(a, b) return "magic: " .. self:add_(a, b) end m = foo:add(9, 8) print(m)
说明:手动绑定的话。參照引擎导出的那些manual.cpp就可以,用tolua的那些接口非常方便。用上面的这样的方式主要是展示这个流程