0

我在 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

附加功能:

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)后才调用 __gc 元方法(t2 对象))。

简单的方法是使用表:

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

但这不是有趣的方式。谢谢!

4

2 回答 2

0

我过去也遇到过同样的问题。这样做的简单原因是 Lua 不知道 C 代码中建立的连接(现在还没有,但我想它会在某个地方完成)。

您不必使用表格方法,只需在 Lua 端链接两个对象/表格/任何内容:

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

请记住,这仅适用于 1:1 的关系。对于更复杂的东西,您仍然必须使用某种表格或类似的方法。可能最干净的方法是在 Lua 端进行链接,并在 C 代码中添加一个回调,以防还有 C 代码要运行。

于 2012-06-30T08:08:28.347 回答
0

您可以在 Lua 注册表中设置它。这实际上是一个只能在 C 代码中访问的全局表。你可以设置registry[t1] = t2;. 只要您在t1's中适当地取消设置它__gc。这也可以扩展到1:n映射,例如您可以registry[t1].insert(t2)为多个“孩子”做的事情。

于 2012-06-30T08:12:33.890 回答