【问题标题】:What is the best practice of passing reference counted C++ objects to Lua?将引用计数的 C++ 对象传递给 Lua 的最佳实践是什么?
【发布时间】:2021-08-27 06:49:28
【问题描述】:

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

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

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

在我更熟悉的 Perl 中,这可以通过增加 XS MapOUTPUT 部分的引用计数并减少销毁器的引用计数来实现。

【问题讨论】:

  • if something wrong with the Lua execution and the __gc is not called, ... would have leak one count - 这意味着你应该在 Lua VM 崩溃时终止你的应用程序。

标签: c++ lua reference-counting


【解决方案1】:

我假设你已经在 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 崩溃或关闭,您可能会泄漏内存。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      • 2022-01-25
      • 2013-09-15
      • 1970-01-01
      • 2011-04-04
      相关资源
      最近更新 更多