luabind を介して、アプリケーションの内部を Lua に公開しています。C++ では、どこにContainer
抽象shared_ptr<Item>
基本Item
クラスがあります。派生クラスには と が含まItemA
れItemB
ます。
これらを 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;
}
これはテーブルに値を設定する正しい方法ですか? スマートポインターを渡すと例外が発生するのは割り当てですが、生のポインターを渡すと、内部でスマートポインターに割り当てられていないようで、オブジェクトがリークされます。ガベージ コレクションを行うことも役に立ちません。