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

What is the best practice of passing reference counted C++ objects to Lua?

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

在将对象添加到 Lua 堆栈之前每次只增加引用计数是否合适且足够?

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

在我比较熟悉的Perl中,这可以通过在XS Map[=27]的OUTPUT部分增加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

每次将引用计数的 C 对象发送到 Lua

时,在 C 端调用 register_object(object)

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

在进一步研究Lua手册后,我发现轻用户数据不支持由Lua机器分配一块内存的元表(参见document). It should be implemented via heavy user data (lua_newuserdatauv)。我可以使用这个内存块放置新的智能指针对象,并在其上绑定一个 __gc