如何同步Lua和C++垃圾回收
我正在尝试将Lua嵌入到现有的C++应用程序中,并通过继承执行工作的类来制定标准程序。我看到的严重问题是,如果在C++环境中释放或删除了公开的对象,那么Lua的调用将导致崩溃。如果内存正在被程序使用“delete”删除,那么我可以编写一个包装器来处理Lua中的释放,但如果内存是由C++分配并在适当的变量超出范围时解除分配,我不知道如何找到这一点,然后在Lua空间中采取适当的操作,有任何想法吗?
谢谢。
原文链接 https://stackoverflow.com/questions/7286486
免责声明:我编写了我要推荐的库。
你可以尝试使用这个 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 结合起来使用的过程,因为它使指针所有权管理变得非常简单直观。
一般来说,几乎所有的 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
将返回空指针。
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
你将需要使用一个 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 资源。