Lua匿名函数存储在C ++中

时间:2014-05-29 10:47:39

标签: c++ lua

我在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,而不是参数中的匿名函数,这将创建一个无限循环。我该如何解决这个问题?

1 个答案:

答案 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?

感谢siffijoeEtab 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函数返回一些东西,哪些不返回。并将返回值更改为正确的值。

参考:luaL_ref()lua_rawgeti()lua_pcall()和误用lua_rawseti()