我在C ++中编写了一个使用回调来实现某些功能的Lua库。为了测试,我有2个Lua函数,Register和Call。它们用C ++实现,如下所示:
int Lua_Register(lua_State* l){
int n = lua_gettop(l);
if(n==1){
if(lua_isfunction(l, -1)){
printf("Register\n")
lua_pushvalue(l, -1);
r = luaL_ref(l, LUA_REGISTRYINDEX);
}
}
return 1;
}
int Lua_Call(lua_State* l){
lua_rawseti(l, LUA_REGISTRYINDEX, r);
lua_call(l, 0, 0);
return 1;
}
然后在Lua:
Register(function()
Log("hi!")
end)
Call()
但我在控制台中看到的很多行包含Register
,后面跟着消息:C stack overflow
。我认为问题是,我存储Register
,而不是参数中的匿名函数,这将创建一个无限循环。我该如何解决这个问题?
答案 0 :(得分:1)
基本上,您尝试使用不存在的值覆盖Lua注册表,而不是执行已设置的值。
你在做什么?
--calling Register()
lua_pushvalue(l, -1); -- now 2 copies of closure on top of stack
r = luaL_ref(l, LUA_REGISTRYINDEX); --one consumed, put into registry, 1 left
--calling Call()
--this C API call has got a new piece of stack
-- which does not contain that leftover of closure copy!
lua_rawseti(l, LUA_REGISTRYINDEX, r); --overwrite Lua registry entry with what?
lua_call(l, 0, 0); --What the heck are we calling now?
感谢siffijoe和Etab Reisner澄清了新的堆栈。
你应该做什么:
我仍然不明白你想要做什么,但是你的Lua代码示例要正确执行(闭包被Call()
调用,你应该检索闭包在使用Lua堆栈顶部不存在的东西执行而不是覆盖之前。像这样:
int Lua_Call(lua_State* l){
lua_rawgeti(l, LUA_REGISTRYINDEX, r); // <--- retrieve closure from registry!
lua_call(l, 0, 0); // <--- consider using lua_pcall()
return 0; // <--- the call does not leave anything useful on the stack.
}
注意:决定,Yours的哪些C API函数返回一些东西,哪些不返回。并将返回值更改为正确的值。