如何获取与给定函数外部的 C 闭包关联的(向上)值?

Val*_*kea 3 c c++ lua pointers

在Lua 5.2手册中我们可以找到以下文字

当创建一个 C 函数时,可以将一些值与其关联,从而创建一个 C 闭包(参见 lua_pushcclosure);这些值称为 upvalues,并且无论何时调用该函数都可以访问该函数。

每当调用 C 函数时,其上值都位于特定的伪索引处。这些伪索引是由宏 lua_upvalueindex 生成的。与函数关联的第一个值位于 lua_upvalueindex(1) 位置,依此类推。对 lua_upvalueindex(n) 的任何访问(其中 n 大于当前函数的 upvalue 数量(但不大于 256))都会产生可接受的(但无效)索引。

因此,我创建了一个与使用“new”创建的对象指针关联的回调函数。

lua_pushstring(L,"myCallbackFunc");
Foo* ideleg = new Foo()
lua_pushlightuserdata (L, (Foo*)ideleg);
lua_pushcclosure(L, LuaCall<Tr,C,Args...>::LuaCallback,1);
lua_settable(L,-3);
Run Code Online (Sandbox Code Playgroud)

所有的机制都工作得很好......但现在是时候清理了,当我取消注册回调函数或退出程序时,我无法取回指针,因此我可以删除它。

我确实使用以下代码片段找到了表条目:

lua_pushnil(L);
while (lua_next(L, -2) != 0)
{
    if (lua_isstring(L, -2) && lua_tostring(L,-2) == "myCallBackFunc" ) 
    {
        // get the pointer back and delete it!
    }
}
Run Code Online (Sandbox Code Playgroud)

(我可以使用 来做到这一点吗lua_getfield(L, -1, "myCallBackFunc");?)

但我无法获得与函数外部的闭包相关的上值LuaCall<Tr,C,Args...>::LuaCallback()(实际上在这个关闭函数内部我可以简单地使用lua_upvalueindex(1),但在这种情况下我在关闭函数之外......)

有没有办法获取这个值,以便我可以在不再需要指针时删除它?


编辑:我确实找到了lua_getupvalue函数,它应该可以满足我的需要,但目前我不知道如何获取闭包堆栈索引。所以它仍然不起作用。

Nic*_*las 5

是的,你可以在 Lua 中做到这一点。但我强烈建议不要这样做。

如果您有权访问该回调,如果它位于 Lua 堆栈上,那么完全有可能某些 Lua 代码也可以访问它。这意味着即使你认为它会被销毁,但实际上直到 Lua 完成它之后它才会被销毁。破坏你的闭包会使其进入非功能状态。然而,因为 Lua 可能仍然可以访问它,所以在销毁它的 upvalue之后,有可能调用闭包。

坏事随之而来。

最好将指针放入完整的用户数据中,并使用__gc元方法附加一个元表来进行清理。这样,您就可以确定当它真正不再使用时,它会被清理掉。

但是,如果您坚持按照自己的方式进行操作,则始终可以使用lua_getupvalue.