Lua用户数据生命周期管理

时间:2019-07-07 19:26:51

标签: c++ lua shared-ptr

我正在从c ++代码中的几个不同位置将c ++对象指针推送到userdata。我希望lua管理c ++对象(userdata)的生命周期。我的问题是,现在我有多个userdata实例指向lua环境中的同一c ++对象。因此,当每个实例都将调用GC。

我在想一种解决方案是在lua注册表中创建一些弱缓存表(LUA_REGISTRYINDEX),以将对象指针映射到实际的用户数据。然后,当我将userdata推送到环境时,我检查该缓存以查看是否已经创建了userdata并推送该实例(否则创建userdata并添加到缓存中)。这样,环境中仅存在一个用户数据实例。

这是最好的解决方案还是我缺少什么?

1 个答案:

答案 0 :(得分:0)

正确的答案是停止这样做:

  

在lua环境中,我有多个userdata实例指向相同的c ++对象

将对象提供给Lua时,Lua拥有该对象。如果指向该对象的指针返回到C ++中,则这些C ++ API应该无法将该对象的所有权授予其他任何地方。 包括再回到Lua。因此,不应有一堆函数可以将指向同一对象的点返回给Lua。

如果确实有很多这样的功能,则需要重新评估Lua是否应该拥有这些对象的所有权,或者是否应该能够使用它们。您会惊讶于您真正需要将对象的所有权交给Lua的情况很少。

如果您绝对无法避免转移所有权,那么这意味着您的所有权语义并不严格。也就是说,没有单个系统拥有一个对象。您在多个地方共享对象的所有权。

在C ++中,其拼写为shared_ptr。因此,您的用户数据应将shared_ptr<T>存储到要管理的对象中。 GC应该销毁shared_ptr,只有在与它共享所有权的T的所有其他实例都已销毁的情况下,GC才会销毁受管理的shared_ptr