Lua匿名函数存储在C++; 我在C++中编写了一个LUA库,它使用回调来实现某些功能。对于测试,我有两个Lua函数,注册和调用。它们在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; } 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. }

Lua匿名函数存储在C++; 我在C++中编写了一个LUA库,它使用回调来实现某些功能。对于测试,我有两个Lua函数,注册和调用。它们在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; } 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. },c++,lua,C++,Lua,然后在卢阿: Register(function() Log("hi!") end) Call() 但我在控制台中看到的是许多行,其中包含寄存器,然后是消息:C堆栈溢出。我假设问题是,我存储的是寄存器,而不是参数中的匿名函数,这将创建一个无限循环。如何解决这个问题?基本上,您正在尝试用不存在的值覆盖Lua注册表,而不是执行已设置的值 简而言之,你在做什么: --calling Register() lua_pushvalue(l, -1); -- now 2 copies of cl

然后在卢阿:

Register(function()
    Log("hi!")
end)

Call()

但我在控制台中看到的是许多行,其中包含
寄存器
,然后是消息:
C堆栈溢出
。我假设问题是,我存储的是
寄存器
,而不是参数中的匿名函数,这将创建一个无限循环。如何解决这个问题?

基本上,您正在尝试用不存在的值覆盖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?
感谢并感谢您对该新堆栈的澄清

你应该做什么:

--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?
我仍然不太明白您到底想做什么,但是在您的Lua代码示例中,我们需要正确执行(closure被
Call()调用)
,您应该在执行之前检索闭包,而不是用Lua堆栈顶部不存在的内容覆盖。类似如下:

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;
}
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.
}
int Lua\u调用(Lua\u状态*l){

卢厄·拉盖蒂(左、卢厄·注册表索引,右);//为什么要在
Lua\u调用
函数的注册表中设置一个值?难道不想从注册表中获取该索引中的值,以便调用它吗?在Clua转换之间,Lua会为您清理堆栈。因此,调用
调用
时,堆栈上应该没有任何内容(如无参数调用).Lua为每个调用提供一个干净的堆栈切片,但Lua堆栈仍然很大,并表明被调用的函数位于当前堆栈切片之前的这个C数组中。这可能也是C堆栈溢出的原因:
Lua\u调用
被自己反复调用。(顺便说一句,在启用API检查的情况下编译Lua应该会检测到此错误。)@EtanReisner,原始问题包含返回非零值的C API函数示例。准确地说,是1。我记得,返回的数字“告诉”Lua VM有多少个值返回到堆栈中而没有被清除。我弄错了吗?@Kamiccolo是的,从C返回的数字是函数放在堆栈上的参数数,Lua应该从堆栈上取下。如果堆栈下溢,则会导致问题。(这是siffijoe所做的API检查注释。)我的观点是,在对C函数的调用之间不会得到相同的堆栈,每次都会得到一个新的堆栈。因此,第二次推送到堆栈上的旧东西不再存在。@Kamiccolo是的,只要你留在C端,你就需要在C函数之间正确地管理堆栈。但是,每次从卢阿。