在luabind中返回指向派生对象的指针时出现泄漏或“未注册类”的问题

时间:2013-03-20 14:07:55

标签: c++ smart-pointers luabind

我通过luabind将我的应用程序的内部暴露给Lua,在C ++中我有一个Container shared_ptr<Item>其中Item是一个抽象基类。派生类包括ItemAItemB

要将这些暴露给luabind,我使用了几个包装类(因为我希望Container在脚本界面中具有不同的编辑机制)。我希望能够在Lua脚本中枚举容器中的Items,如下所示:

container=app.container
for i,event in ipairs(container.items) do 
  print(tostring(event))
end

我遇到的问题是我可以通过将原始指针返回到ItemWrappers来公开此功能,但这会导致内存泄漏,因为永远不会调用ItemWrapper析构函数。如果我尝试将luabind中的包装器声明为智能指针as described in the docs,那么当我尝试将智能指针作为lua对象返回时,会抛出'尝试使用未注册的类'异常。

包装器的定义如下:

class ContainerWrapper {
public:
   ContainerWrapper(Container& c) : container(c) {};
   Container&  c;  // reference to the actual container
};

class ItemWrapper {
public:
  virtual ~ItemWrapper() {};
  ItemWrapper(int itemIndex_) : itemIndex(itemIndex_) {};
  int   itemIndex;  // items are addressed by index
};

class ItemAWrapper : public ItemWrapper {
public:
  ItemAWrapper(int itemIndex_) : ItemWrapper(itemIndex_) {};
};

luabind注册看起来像这样:(如果我不使用智能指针)

class_<ItemWrapper>("Item") ,
class_<ItemAWrapper, ItemWrapper>("ItemA")

如果我这样做就像这样:

class_<ItemWrapper, std::tr1::shared_ptr<ItemWrapper> >("Item") ,
class_<ItemAWrapper, ItemWrapper, std::tr1::shared_ptr<ItemWrapper> >("ItemA")

公开items Container成员的函数返回一个lua表:

luabind::object Container::getItemsAsTable(lua_State* L)
{
  luabind::object table=luabind::newtable(L);
  for (int i=0; i<items.size(); i++) {
    table[i+1]= new ItemAWrapper(); // or function to return pointer/smart pointer
  }
  return table;
 }

这是在表格中设置值的正确方法吗?如果我传递一个智能指针,它就是生成异常的赋值,但如果我传递一个原始指针,那么它似乎不会在内部将它分配到一个智能指针中,并且该对象会被泄露。进行垃圾收集也无济于事。

1 个答案:

答案 0 :(得分:1)

Lua已经是多态的。因此,getItemsAsTable函数不需要new这些ItemWrapper个对象。只需坚持其中的价值观。像这样:table[i+1] = ItemAWrapper()。除非你需要使用指针(如果更改Lua表应该反映在C ++中),否则不要打扰。只需使用一个值。