Cocos2d-x3.0如何绑定调用lua回调函数

(假设你已经会使用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;
}



你可能感兴趣的:(Cocos2d-x3.0)