[✔️]c++返回2个值给lua,tolua如何处理c++函数重载

265 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天,点击查看活动详情

项目中将部分的lua逻辑迁徙到c++,迁徙的过程中发现lua的function返回的是2个值,为了保证使用的统一性,也希望c++处理后,返回给lua的值数量保持不变。

cocos2dx 中返回2的情况

默认参数

  • binding
 if (argc == 1)
{
    cocos2d::Vec2 arg0;

    ok &= luaval_to_vec2(tolua_S, 2, &arg0, "cc.TMXLayer:getTileGIDAt");
    unsigned int ret = cobj->getTileGIDAt(arg0);
    tolua_pushnumber(tolua_S,(lua_Number)ret);
    tolua_pushnumber(tolua_S,(lua_Number)0);
    return 2;
}
if (argc == 2)
{
    cocos2d::Vec2 arg0;
    int arg1;

    ok &= luaval_to_vec2(tolua_S, 2, &arg0, "cc.TMXLayer:getTileGIDAt");
    ok &= luaval_to_int32(tolua_S, 3, &arg1, "cc.TMXLayer:getTileGIDAt");

    unsigned int ret = cobj->getTileGIDAt(arg0, (cocos2d::TMXTileFlags*)&arg1);
    tolua_pushnumber(tolua_S,(lua_Number)ret);
    tolua_pushnumber(tolua_S,(lua_Number)arg1);// 第二个参数
    return 2;
}
  • cpp
uint32_t TMXLayer::getTileGIDAt(const Vec2& pos, TMXTileFlags* flags/* = nullptr*/)

指针

  • binding
if (argc >= 0 && argc <= 2)
{
    float x = (float)  tolua_tonumber(tolua_S,2,0);
    float y = (float)  tolua_tonumber(tolua_S,3,0);

    self->getPosition(&x,&y);

    tolua_pushnumber(tolua_S,(lua_Number)x);
    tolua_pushnumber(tolua_S,(lua_Number)y);

    return 2;
}
  • cpp
void Node::getPosition(float* x, float* y) const
{
    *x = _position.x;
    *y = _position.y;
}

分析

返回多个值,写法有点特殊,有点怀疑是后期人为修改的

6045340c5aadd874bb8d973bed9232d.png

在lua模板文件中,也确实没有找到return 2的关键代码

dbc733e64c8c92f683ec2509b7a108a.png

至此,基本可以确认return 2的代码大部分都是后期人为修改的

tools\bindings-generator\targets\lua\conversions.yaml中也并没有关于return 2的相关模板配置

cocos2dx是如何处理c++函数重载

argc = lua_gettop(tolua_S)-1;

do 
{
    if (argc == 4)
    {
        cocos2d::Vec2 arg0;
        // 里面会进行类型的检查,如果失败,在debug模式就会主动报错,并返回false     
        ok &= luaval_to_vec2(tolua_S, 2, &arg0, "MapUtil:getRectDif_KeyGridIndex");
        if (!ok) { break; }
        int arg1;
        ok &= luaval_to_int32(tolua_S, 3,(int *)&arg1, "MapUtil:getRectDif_KeyGridIndex");
        if (!ok) { break; }
        cocos2d::Vec2 arg2;
        ok &= luaval_to_vec2(tolua_S, 4, &arg2, "MapUtil:getRectDif_KeyGridIndex");
        if (!ok) { break; }
        int arg3;
        ok &= luaval_to_int32(tolua_S, 5,(int *)&arg3, "MapUtil:getRectDif_KeyGridIndex");
        if (!ok) { break; }
        std::map<int, cocos2d::Vec2, std::less<int>, std::allocator<std::pair<const int, cocos2d::Vec2> > > ret = MapUtil::getRectDif_KeyGridIndex(arg0, arg1, arg2, arg3);
        std_map_int_vec2_to_luaval(tolua_S, ret);
        return 1;
    }
} while (0);
// 如果以上类型转换失败,还有会进行下边的类型转换
ok  = true;
do 
{
    if (argc == 4)
    {
        int arg0;
        ok &= luaval_to_int32(tolua_S, 2,(int *)&arg0, "MapUtil:getRectDif_KeyGridIndex");
        if (!ok) { break; }
        int arg1;
        ok &= luaval_to_int32(tolua_S, 3,(int *)&arg1, "MapUtil:getRectDif_KeyGridIndex");
        if (!ok) { break; }
        int arg2;
        ok &= luaval_to_int32(tolua_S, 4,(int *)&arg2, "MapUtil:getRectDif_KeyGridIndex");
        if (!ok) { break; }
        int arg3;
        ok &= luaval_to_int32(tolua_S, 5,(int *)&arg3, "MapUtil:getRectDif_KeyGridIndex");
        if (!ok) { break; }
        std::map<int, cocos2d::Vec2, std::less<int>, std::allocator<std::pair<const int, cocos2d::Vec2> > > ret = MapUtil::getRectDif_KeyGridIndex(arg0, arg1, arg2, arg3);
        std_map_int_vec2_to_luaval(tolua_S, ret);
        return 1;
    }
} while (0);
ok  = true;
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d", "MapUtil:getRectDif_KeyGridIndex",argc, 4);
return 0;