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
相关产品推荐
相关产品推荐

