1

std::shared_ptr を受け取る関数があり、Derived 型のオブジェクトを Python からこの関数に渡したいと考えています。これが私のクラス定義です:

struct AbstractBase {
    virtual void foo() = 0;
};

struct Derived : public AbstractBase {
    virtual void foo(){
        std::cout<<"Derived's foo!"<<std::endl;
    }
};

struct Unrelated {
    void bar(std::shared_ptr<AbstractBase> base_shared_ptr) {
        base_shared_ptr->foo();
    }
};
#endif /* CLASSES_H */

シンプルな純粋な C++ の例は、私が望むことを行います。

int main()
{
    std::shared_ptr<Derived> d(new Derived);
    Unrelated u;
    u.bar(d);
}

出力:Derived's foo!

ここに私のBoost.Pythonラッパーコードがあります:

#include <boost/python.hpp>
#include "classes.h"


BOOST_PYTHON_MODULE(shared_ptr_test) {
    using namespace boost::python;
    class_<AbstractBase,std::shared_ptr<AbstractBase>,boost::noncopyable>("AbstractBase",no_init);

    class_<Derived,std::shared_ptr<Derived>,bases<AbstractBase>,boost::noncopyable>("Derived");

    class_<Unrelated,std::shared_ptr<Unrelated>,boost::noncopyable>("Unrelated")
        .def("bar",&Unrelated::bar);
}

そして、ここに私の簡単なpythonテストがあります:

import shared_ptr_test

d=shared_ptr_test.Derived()
u=shared_ptr_test.Unrelated()
u.bar(d)

残念なことに、これはうまくいきません。正常にコンパイルされますが、python スクリプトを実行すると、次のエラーが発生します。

Traceback (most recent call last):
  File "test.py", line 5, in <module>
    u.bar(d)
Boost.Python.ArgumentError: Python argument types in
    Unrelated.bar(Unrelated, Derived)
did not match C++ signature:
    bar(Unrelated {lvalue}, std::shared_ptr<AbstractBase>)

これを修正するように変更barすると、shared_ptr<Derived>Boost.Python が内部的にオブジェクトをshared_ptrs で管理していることがわかります。Boost.Python に、ashared_ptr<Derived>を期待する関数に aを渡しても問題ないことを認識させるために、さらに何かする必要がありshared_ptr<Base>ますか?

4

1 に答える 1

2

Boost.Python は、 へDerivedのスマート ポインタを へのスマート ポインタに変換できることに注意する必要がありますAbstractBase。これは、次のいずれかによって実現できます。

  • を使用しboost::shared_ptrます。Boost.Python には、階層型boost::shared_ptrの s間の暗黙的な変換を処理するコードがあります。element_type
  • std::shared_ptr<Derived>からstd::shared_ptr<AbstractBase>viaへの暗黙的な変換を登録しboost::python::implicitly_convertibleます。 std::shared_ptrの概念要件を満たしているためimplicitly_convertible、変換をモジュール定義に登録するだけで済みます。

    implicitly_convertible<std::shared_ptr<Derived>,          // Source
                           std::shared_ptr<AbstractBase> >(); // Target
    
于 2013-05-31T14:28:31.633 に答える