(假设你已经会使用tolua导出自定义类)
首先,在C++先写一个类,里面包含这么一个函数
void registerScriptFuncHandler(int handler)
{
return;
}
没错,这个函数什么都不用做。
接着使用 genbinding.py 导出类
你会得到一个不能用的导出函数
int lua_MyClass_MyPrefix_registerScriptFuncHandler(lua_State* tolua_S)
不能用的原因是 ok &= luaval_to_int32(tolua_S, 2,(int *)&arg0); 这一句。tolua抽风把一个函数类型错误地翻译成了整型,所以你在lua调用这个函数地时候会提示类型错误,期待的是一个整型值。
我把修改的正确示范贴出来
int lua_MyClass_MyPrefix_registerScriptFuncHandler(lua_State* tolua_S)
{
int argc = 0;
FRAccordion* cobj = nullptr;
#if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
#endif
#if COCOS2D_DEBUG >= 1
if (!tolua_isusertype(tolua_S,1,"FRAccordion",0,&tolua_err)) goto tolua_lerror;
#endif
cobj = (FRAccordion*)tolua_tousertype(tolua_S,1,0);
#if COCOS2D_DEBUG >= 1
if (!cobj)
{
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_MyClass_MyPrefix_registerScriptFuncHandler'", nullptr);
return 0;
}
#endif
argc = lua_gettop(tolua_S)-1;
if (argc == 1)
{
if(!toluafix_isfunction(tolua_S,2,"LUA_FUNCTION",0,&tolua_err))
{
goto tolua_lerror;
}
LUA_FUNCTION handler = (toluafix_ref_function(tolua_S,2,0));
ScriptHandlerMgr::HandlerType handlerevent = ScriptHandlerMgr::HandlerType((int)ScriptHandlerMgr::HandlerType::EVENT_CUSTIOM);
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)cobj, handler, handlerevent);
return 0;
}
CCLOG("%s has wrong number of arguments: %d, was expecting %d \n", "registerScriptFuncHandler",argc, 1);
return 0;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'lua_MyClass_MyPrefix_registerScriptFuncHandler'.",&tolua_err);
#endif
return 0;
}
if (argc == 1)
{
if(!toluafix_isfunction(tolua_S,2,"LUA_FUNCTION",0,&tolua_err))
{
goto tolua_lerror;
}
LUA_FUNCTION handler = (toluafix_ref_function(tolua_S,2,0));
ScriptHandlerMgr::HandlerType handlerevent = ScriptHandlerMgr::HandlerType((int)ScriptHandlerMgr::HandlerType::EVENT_CUSTIOM);
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)cobj, handler, handlerevent);
return 0;
}
注意红色字,就是应该修改成的样子。绿色字部分就是将我们的回调函数委托给ScriptHandlerMgr,我们通过他来调用我们的lua回调函数。
单独来看一下
首先,先定义回调函数的类型,这里设置的是用户自定义类型EVENT_CUSTIOM
ScriptHandlerMgr::HandlerType handlerevent = ScriptHandlerMgr::HandlerType((int)ScriptHandlerMgr::HandlerType::EVENT_CUSTIOM);
接着添加到管理器里,第一个参数就是调用的对象,第二个是函数句柄ID,第三个就是我们刚刚定义的类型类实例
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)cobj, handler, handlerevent);
OK,绑定到这里就算是已经完成了
先看看lua端怎么注册函数
xx.registerChangeScriptFunc(function () print(“hey pretty”) return true end)
这样就注册了个匿名函数给C++端了,这里return true是为了在C++调用返回时如果正确会返回True,而C++端调用的时候如果函数不存在,运行错误,都会返回0 ,如果这里不设置返回值的话,就没有办法区分开来了。
接下来看C++ 怎么调用
首先include 头文件
#include "CCLuaEngine.h"
#include “LuaScriptHandlerMgr.h"
auto engine = LuaEngine::getInstance();
EventCustom value("ContentCallback");
BasicScriptData data(this,(void*)&value);
if(engine->handleEvent(ScriptHandlerMgr::HandlerType::EVENT_CUSTIOM,(void*)&data))
{
return;
}
第一步,获取一下当前的lua引擎实例。
第二步,实例化一个EventCustom对象,这个对象是可以设置userdata(void*)的,但是我暂时不知道有什么用。
第三步,实例化一个BasicScriptData对象,第一个参数是事件所绑定的对象,这里设置是this,表示自己调用的。value则是传入的Userdata。
第四步,真正调用LuaEngine的方法来发射事件
参数1是事件类型,参数2就是BasicScriptData
engine->handleEvent(ScriptHandlerMgr::HandlerType::EVENT_CUSTIOM,(void*)&data)
函数的返回值就是Lua函数返回的值,目前只能返回一个布尔值和整形值。
若这个函数执行错误或者不存在则会返回 0
YEAH~你会在C++调用Lua回调函数了!
最后一步,在你的C++自定义类里删掉
void registerScriptFuncHandler(int handler)
{
return;
}