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

本文详细介绍了如何在C++中使用tolua导出自定义类,并正确绑定Lua回调函数。通过修改tolua生成的绑定代码,使C++能够正确识别并调用Lua中的函数。文章还解释了如何在C++端注册和调用这些Lua回调,包括错误处理和返回值的检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

原文:https://blog.youkuaiyun.com/xilong_li/article/details/38313293 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值