如何获取与 C 闭包关联的(上)值,这些闭包在给定函数之外?

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

当创建一个 C 函数时,可以将一些值与它关联,从而创建一个 C 闭包(参见 lua_pushcclosure);这些值称为上值(upvalues),每次调用函数时该函数均可访问这些值。

每当调用 C 函数时,它的上值都会位于特定的伪索引中。这些伪索引是由宏lua_upvalueindex产生的。与函数关联的第一个值位于位置lua_upvalueindex(1),以此类推。任何对lua_upvalueindex(n)的访问,其中n大于当前函数的上值数量(但不大于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);

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

我使用以下代码段找到表项:

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!
    }
}

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

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

有没有一种方法可以获得此值,以便在不需要时删除指针?

原文链接 https://stackoverflow.com/questions/10377950

点赞
stackoverflow用户734069
stackoverflow用户734069

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

如果你能够访问那个回调函数,如果它在Lua堆栈上,那么某些Lua代码就完全可以访问它。这意味着,即使你认为它将被销毁,直到Lua完成它,它实际上不会被销毁。破坏你的闭包会使它处于一个不工作的状态。然而,因为Lua可能仍然可以访问它,所以在你破坏了它的upvalue之后,闭包仍然有可能被调用。

不好的事情会发生。

更好的方法是将指针放入一个完整的用户数据中,并附加一个元表,其中包含一个__gc元方法来进行清理。这样,你可以确定它将在真正不再使用时清理。

然而,如果你坚持要按照你的方式做,你总是可以使用lua_getupvalue

2012-04-30 03:20:58