9

C++ の shared_ptr に保持されているオブジェクトがあります。オブジェクトは、python 内から python バインディングを介してアクセスされ、それを保持しようとする別のバインドされた C++ 関数に渡されます。オブジェクトが C++ から Python に移行すると、shared_ptr から Python オブジェクトに変換されるようです。その後、C++ に戻ると、python オブジェクトから新しい shared_ptr に変換されますが、この shared_ptr は、最初に保持されていた shared_ptr とは無関係です。

python オブジェクトから shared_ptr への変換が元の shared_ptr 内部を参照するように、boost-python バインディングをセットアップすることは可能ですか?

以下は、問題を示すために使用した要約コードです。

この例では、オブジェクトは最初に s_initial という名前の shared_ptr に保持されます。これは、getSharedPtr 関数を介して Python 内から取得され、putSharedPtr 関数を介して C++ にプッシュされます。putSharedPtr 内では、weak_ptr s_copied にコピーされます。デバッガーでポインターを調べると、putSharedPtr で使用されている shared_ptr が、s_initial と同じ参照カウント内部構造を持っていないことがわかります。ウィーク ポインター s_copied は 1 つのストロング ポインター (putSharedPtr で使用されるポインター) にのみ関連付けられており、putSharedPtr が完了するとそのポインターは破棄されたため、最終的なアサートが発生します。

static shared_ptr<Captured> s_initial;
static weak_ptr<Captured> s_copied;

class UseSharedPtr
{
public:
    shared_ptr<Captured> getSharedPtr()
    {
        return s_initial;
    }

    void putSharedPtr(shared_ptr<Captured> ptr)
    {
        s_copied = ptr;
    }
};


BOOST_PYTHON_MODULE(test)
{
    class_<Captured, shared_ptr<Captured>, boost::noncopyable>("Captured", no_init);
    class_<UseSharedPtr, boost::noncopyable>("UseSharedPtr", init<>())
        .def("getSharedPtr", &UseSharedPtr::getSharedPtr)
        .def("putSharedPtr", &UseSharedPtr::putSharedPtr)
    ;
}



    s_initial = make_shared<Captured>();

    const char* chunk = "\
from test import UseSharedPtr \n\
x = UseSharedPtr() \n\
ptr = x.getSharedPtr() \n\
x.putSharedPtr(ptr)\n\
del x \n\
del ptr \n\
";
    object result = exec(chunk, mainNamespace, mainNamespace);

    assert(s_copied.lock());
4

2 に答える 2

0

class_<UseSharedPtr, shared_ptr<UseSharedPtr>, boost::noncopyable>boost::pythonがshared_ptrを使用してオブジェクトを管理する必要があることを認識できるようにする必要があります。確認してほしい場合は、例をコンパイル可能にしてください。

于 2012-11-28T12:43:32.413 に答える