如何同步Lua和C++垃圾回收

我正在尝试将Lua嵌入到现有的C++应用程序中,并通过继承执行工作的类来制定标准程序。我看到的严重问题是,如果在C++环境中释放或删除了公开的对象,那么Lua的调用将导致崩溃。如果内存正在被程序使用“delete”删除,那么我可以编写一个包装器来处理Lua中的释放,但如果内存是由C++分配并在适当的变量超出范围时解除分配,我不知道如何找到这一点,然后在Lua空间中采取适当的操作,有任何想法吗?

谢谢。

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

点赞
stackoverflow用户298661
stackoverflow用户298661

你将需要使用一个 RAII 包装器,它可以使用 registry 绑定到 Lua 实例,并使用表格将值公开给 Lua——当你完成后可从此删除一个内部指针。

template<typename T> class LuaExposedValue {
    T t;
    lua_State* ls;
public:
    LuaExposedValue(lua_State* L) {
        // 设置 registry[&t] = { &t }
        ls = L;
    }
    ~LuaExposedValue() {
        // 从表格中删除 &t
    }
}

或者,只需在变量消失后禁止 Lua 访问它,并让脚本编写者自行处理。

最后,你可以使用 Lua GC 分配所有可访问的 Lua 资源。

2011-09-02 16:38:20
stackoverflow用户63791
stackoverflow用户63791

免责声明:我编写了我要推荐的库。

你可以尝试使用这个 LuaWrapper 库,它看起来可以处理你试图做的事情。它甚至不是一个真正的库,只是一个头文件。

你可以使用 luaW_push<MyType>(L, myObj); 将你的对象推入 Lua 中。除非你在它们上运行 luaW_hold<MyType>,Lua 不会拥有你从 C++ 创建的对象。换句话说,除非你告诉 Lua,否则它不会垃圾回收你的对象。

相反,你可以在你的 Lua 代码中使用 MyType.new() 创建一个对象,Lua 会拥有它。它将被垃圾回收,就像你所期望的那样。如果你想将所有权交给 C++,你可以在你的对象上调用 luaW_release<MyType>

还有一些像 luaW_to<MyType>luaW_check<MyType> 这样的函数,并且在有限的程度上,它正确地支持从基础类型继承(尽管它目前只允许单一继承)。我发现这极大地简化了我的尝试将 C++ 和 Lua 结合起来使用的过程,因为它使指针所有权管理变得非常简单直观。

2011-09-02 18:05:02
stackoverflow用户734069
stackoverflow用户734069

一般来说,几乎所有的 Lua 封装都有一种方式来决定谁拥有什么内存。也就是说,一个对象是被 Lua 拥有(并因此被删除)还是被你的应用拥有。

如果你向 Lua 提供了一个由 C++ 拥有的对象指针,则必须找到一种方法来确保在 C++ 删除它后,Lua 不再使用该指针。有几种避免这种情况的方法。一种方法是将所有权转移给 Lua。

另一种方法是使用 boost/std::shared_ptr,它允许你在 C++ 和 Lua 之间共享所有权。如果你手动执行此操作,则在 Lua 中创建一些非轻量 userdata,它的大小为 shared_ptr 的大小。你将一个清理元方法附加到它上面,以便销毁 shared_ptr,并使用放置 new 在 Lua userdata 上构造 shared_ptr。Luabind实际上本身就有这个功能:如果你向 Lua 传递一个 shared_ptr,则它们两者都共享内存的所有权。

你也可以使用 boost/std::weak_ptr。这是一个对象,你可以通过查询它来获取一个 shared_ptr。这个想法是,你不应该长期保留指针;你需要根据需要临时查询它,但你只存储 weak_ptr。如果对象已经失去了所有的 shared_ptr 引用,那么查询 weak_ptr 将返回空指针。

2011-09-02 21:14:56