lua_pushcclosure无法捕获上值问题及Lua闭包CAPI实现咨询
问题解决:Lua C API lua_pushcclosure 上值捕获失败
错误原因分析
尝试代码1的问题
你创建了带2个上值的闭包,但后续调用Set_Callback时,传递的是原始的C函数(通过lua_pushcfunction),而非之前创建的闭包。原始函数没有绑定任何上值,自然无法获取到param1和param2。
尝试代码2的问题
lua_pcall的参数错误:Set_Callback只需要接收1个回调参数,但你传入了3个参数。实际上,lua_pushcclosure(L, my_callback, 2)会弹出栈顶的2个字符串作为上值,最终栈上只有Set_Callback和闭包两个元素,调用时参数数量应为1,而非3。
正确实现代码
以下是对应纯Lua闭包逻辑的C API实现:
static int my_callback(lua_State* L) { std::cout << "my_callback" << std::endl; // 安全获取上值:先检查是否为字符串类型 const char* param1 = lua_tostring(L, lua_upvalueindex(1)); const char* param2 = lua_tostring(L, lua_upvalueindex(2)); std::cout << "PARAM1:" << (param1 ? param1 : "nil") << std::endl; std::cout << "PARAM2:" << (param2 ? param2 : "nil") << std::endl; return 0; } // 正确步骤: lua_getfield(L, index, "Set_Callback"); // 栈:[Set_Callback] lua_pushstring(L, "param1"); // 栈:[Set_Callback, "param1"] lua_pushstring(L, "param2"); // 栈:[Set_Callback, "param1", "param2"] lua_pushcclosure(L, my_callback, 2); // 弹出2个上值,压入闭包,栈:[Set_Callback, closure] // 调用Set_Callback,传入1个参数(闭包),无返回值 int status_lua_pcall = lua_pcall(L, 1, 0, 0); if (status_lua_pcall != LUA_OK) { // 处理调用错误,比如打印Lua错误信息 std::cerr << "Lua error: " << lua_tostring(L, -1) << std::endl; lua_pop(L, 1); }
关键说明
- 闭包创建与传递:必须将
lua_pushcclosure创建的闭包直接作为参数传递给Set_Callback,不能再传递原始C函数。 - 栈操作顺序:先压入上值,再调用
lua_pushcclosure,该函数会自动弹出指定数量的栈顶元素作为闭包的上值。 lua_pcall参数:第二个参数是传递给被调用函数的参数数量,这里Set_Callback只需要1个回调参数,所以传入1。- 安全获取上值:使用
lua_tostring前最好检查返回值是否为NULL,避免空指针输出。
内容的提问来源于stack exchange,提问作者Lua_beg
相关产品推荐
相关产品推荐

