【问题标题】:LUA C API - weak references with luaL_refLUA C API - 使用 luaL_ref 的弱引用
【发布时间】:2013-10-20 20:43:04
【问题描述】:

下面的例子:

int r = luaL_ref(L, LUA_REGISTRYINDEX);

r 将是对堆栈顶部对象的强引用。

是否可以获得对栈顶对象的弱引用?

我正在考虑的一种方法是创建一个具有弱值的表并将其存储在全局注册表中。然后在需要弱值时使用它。

有更简单的方法吗?

Lua 2.4 的文档中有这个,但 luaL_ref 现在的工作方式似乎有所不同。:

函数 lua_ref 创建一个对对象的引用,该对象位于 栈顶,并返回此引用。如果 lock 为真,则 对象被锁定:这意味着对象不会被垃圾回收

【问题讨论】:

  • @Kamiccolo 这个问题专门针对luaL_ref。我一直在寻找有关如何实现它的 C API 解决方案。

标签: c lua lua-table


【解决方案1】:

这是我想出的解决方案:

int create_ref(bool weak_ref)
{
    lua_newtable(L); // new_table={}

    if (weak_ref) {
        lua_newtable(L); // metatable={}            

        lua_pushliteral(L, "__mode");
        lua_pushliteral(L, "v");
        lua_rawset(L, -3); // metatable._mode='v'

        lua_setmetatable(L, -2); // setmetatable(new_table,metatable)
    }

    lua_pushvalue(L,-2); // push the previous top of stack
    lua_rawseti(L,-2,1); // new_table[1]=original value on top of the stack

    //Now new_table is on top of the stack, rest is up to you
    //Here is how you would store the reference:
    return luaL_ref(L, LUA_REGISTRYINDEX); // this pops the new_table
}

通过这个函数,我可以存储弱引用和强引用。只需 1 个额外的表作为开销(或 1+metatable 用于弱引用)。

【讨论】:

  • 是的,这是唯一真正的方法,除了与用户数据值相关的用户值,这些值也很弱。但这条路线特定于使用 userdata 对象,可能不适用于您的情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-20
  • 1970-01-01
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多