Lua 对象之间的引用。

我在 C 中实现了 Simple Lua 类。类的用法:

require("test")
function foo()
    local t1 = test()
    local t2 = test()
    t1:attach(t2)
    return t1
end
o = foo()
-- some code
o = nil

attach 函数:

int class_attach(lua_State *L)
{
    module_data_t *mod = luaL_checkudata(L, 1, "test");
    luaL_checktype(L, 2, LUA_TUSERDATA);
    module_data_t *child = lua_touserdata(L, 2);
    printf("%p->%p\n", (void *)mod, (void *)child);
    return 0;
}

从函数返回后,t2 对象将通过 GC 清除。是否可能防止这种情况发生,设置 t1 和 t2 对象之间的引用关系?(只有在父模块(t1)清除后才调用 t2 对象的 __gc 元方法)。

简单的方法是使用表格:

function foo()
    ret = {}
    ret[1] = test()
    ret[2] = test()
    ret[1]:attach(ret[2])
    return ret
end

但那并不是有趣的方法。 谢谢!

点赞
用户409744
用户409744

我以前也遇到过同样的问题。简单的原因是 Lua 不知道在 C 代码中建立的连接(目前没有,但我猜以后会在某处完成)。

你不必采用表格的方法,只需在 Lua 端将两个对象/表/等等链接起来即可:

function foo()
    local t1 = test()
    local t2 = test()
    t1:attach(t2)
    t1._dummy_link = t2
    return t1
end

只需记住,这仅适用于一对一的关系。对于更复杂的内容,您仍然需要使用某种类型的表格或类似方法。最干净的方法可能是在 Lua 端进行链接,并在需要运行 C 代码时添加一个回调到 C 中。

2012-06-30 08:08:28
用户298661
用户298661

你可以在 Lua 的注册表中设置它。这实际上是一个全局表,只能在 C 代码中访问。您可以设置 registry[t1] = t2;。只要您恰当地在 t1__gc 中取消设置,就可以了。这也可以适用于 1:n 映射,例如,您可以为多个“子项”执行 registry[t1].insert(t2)

2012-06-30 08:12:33