You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++嵌入Lua给注册函数传表参数时报attempt to call a table value错误如何解决

C++嵌入Lua调用注册钩子函数报错问题解决方案

错误根因

你触发attempt to call a table value错误的核心原因是调用lua_pcall时,栈顶位置是你构造的table而非要执行的钩子函数,Lua误将table当做函数执行触发报错,具体栈逻辑错误如下:

  • 进入lua_addHook函数时,栈上参数顺序为:栈底 -> 参数1(字符串) -> 参数2(字符串) -> 参数3(test1函数) -> 栈顶
  • 你连续调用两次lua_newtable后,栈变为:原有参数 -> 无名空table -> 构造好的varlist table -> 栈顶
  • 执行lua_pcall(L, 1, 0, 0)时,Lua默认栈顶往下数参数个数+1的位置是待执行函数,也就是此时栈顶的varlist table,直接触发类型错误
  • 额外冗余问题:你第一次创建的空table没有任何作用,属于多余创建;函数最后的return 1也没有对应返回值,不符合Lua C API规范

修复代码

修改后的lua_addHook函数逻辑如下:

static int lua_addHook(lua_State* L) {
    if (lua_isstring(L, 1) && lua_isstring(L, 2) && lua_isfunction(L, 3)) {
        // 第一步:先把要调用的钩子函数压到栈顶
        lua_pushvalue(L, 3);
        
        // 第二步:构造要传入的参数table
        lua_newtable(L);
        for (size_t i = 0; i < 3; ++i) {
            lua_pushinteger(L, i + 1);
            lua_pushstring(L, ("string varlist: " + std::to_string(i)).c_str());
            lua_settable(L, -3);
        }
        
        // 第三步:调用函数,1个参数,0个返回值
        if (lua_pcall(L, 1, 0, 0) != 0) {
            printf("error: %s\n", lua_tostring(L, -1));
            lua_pop(L, 1);
        }
    }
    // 该函数不需要给Lua返回值,返回0
    return 0;
}

修改后运行即可输出你预期的三行内容。

内容的提问来源于stack exchange,提问作者hertz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 10:09:08