1

luabind を介して、アプリケーションの内部を Lua に公開しています。C++ では、どこにContainer抽象shared_ptr<Item>基本Itemクラスがあります。派生クラスには と が含まItemAItemBます。

これらを luabind に公開するために、いくつかのラッパー クラスを使用します (スクリプト インターフェイスで別の編集メカニズムをコンテナーに持たせたいため)。次のように、Lua スクリプトでコンテナー内のアイテムを列挙できるようにしたいと考えています。

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

私が抱えている問題は、生のポインターを に返すことでこの機能を公開できることですが、デストラクタが呼び出されないItemWrappersため、メモリ リークが発生します。ドキュメントで説明されているようにItemWrapper、luabind でラッパーをスマート ポインターとして宣言しようとすると、スマート ポインターを 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;
 }

これはテーブルに値を設定する正しい方法ですか? スマートポインターを渡すと例外が発生するのは割り当てですが、生のポインターを渡すと、内部でスマートポインターに割り当てられていないようで、オブジェクトがリークされます。ガベージ コレクションを行うことも役に立ちません。

4

1 に答える 1