将引用计数的 C++ 对象传递给 Lua 的最佳实践是什么?

问题描述

我想让我的引用计数 C++ 对象也在 Lua 回调中管理:当它被一个 Lua 变量持有时,增加它的引用计数;当 Lua 变量被销毁时,释放一个 refcount。 __gc方法似乎可以自动执行释放端,但如何实现增加端?

每次在将对象添加到 Lua 堆栈之前增加 refcount 是否合适?

或者我应该新建一个智能指针对象,在 Lua C 函数中到处使用它,然后在 __gc方法删除它?这看起来很丑,好像 Lua 执行出了问题,__gc 没有被调用new ed 智能指针对象将被泄漏,并且它所引用的引用计数对象将泄漏一个计数。

在我更熟悉的 Perl 中,这可以通过增加 XS MapOUTPUT 部分的 refcount 和减少 destroyer 的 refcount 来实现.

解决方法

我假设您已经在 C 中实现了两个 Lua 函数:inc_ref_count(obj)dec_ref_count(obj)

local MT = {__gc = dec_ref_count}
local setmetatable = setmetatable
local T = setmetatable({},{__mode="k"})

function register_object(obj)
   if not T[obj] then
      T[obj] = setmetatable({},MT)
      inc_ref_count(obj)
   end
end

每次向 Lua 发送引用计数的 C 对象时,在 C 端调用 register_object(object)

如果 Lua VM 崩溃或关闭,您可能会泄漏内存。

,

仔细研究了Lua手册,发现轻用户数据不支持元表(见document)。它应该通过 Lua 机器分配一块内存的大量用户数据 (lua_newuserdatauv) 来实现。我可以使用这个内存块放置一个新的智能指针对象,并在它上面绑定一个 __gc