2011-11-17 53 views
6

私はBoost.Pythonを使用してC++ライブラリ用のラッパーを作成していますが、何か問題があります。例えば、私は、次のコードを持っています:pythonでそうBoost.PythonとC++ std ::ポインタのベクトル

class Base 
{ 
public: 
    virtual void func() = 0; 
}; 

class Derived : public Base 
{ 
public: 
    virtual void func() 
    { 
     cout << "Derived::func()"<< endl; 
    } 
}; 


// wrapper for Base 
struct BaseWrapper : Base, python::wrapper<Base> 
{ 
    virtual void func() 
    { 
     this->get_override("func"); 
    } 
}; 


Base* makeDerived() 
{ 
    return new Derived; 
} 

vector<Base*>* makeDerivedVec() 
{ 
    vector<Base*> *v = new vector<Base*>; 
    v->push_back(new Derived); 
    v->push_back(new Derived); 
    v->push_back(new Derived); 
    return v; 
} 

BOOST_PYTHON_MODULE(mylib) 
{ 
    // export Base 
    class_<BaseWrapper, noncopyable>("Base") 
      .def("func", pure_virtual(&Base::func)); 

    class_<vector<Base*> >("BasePtrVec") 
      .def(vector_indexing_suite<vector<Base*> >()); 

    // export Derived 
    class_<Derived, bases<Base> >("Derived") 
      .def("func", &Derived::func); 

    // export makeDerived() 
    def("makeDerived", &makeDerived, return_value_policy<manage_new_object>()); 

    // export makeDerivedVec() 
    def("makeDerivedVec", &makeDerivedVec, return_value_policy<manage_new_object>()); 
} 

が、私はそれをコンパイルし、輸入をして、この試してみてください。

B = mylib.Base()b.func()

D = mylib.makeDerived()d.func()は

最初の行は、予想通り、そのb.func()は仮想的に純粋であると言って例外をスローし、2行目は

をプリントアウト
派生

:: funcを()

そして、それは大丈夫です。

しかし、コード

dlist = mylib.makeDerivedVec() 
for d in dlist: 
    d.func() 

が動作しない、とPythonが例外をスロー:それは正しくベース* makeDerived(によって返された)を取り扱い、ベースで動作することを拒否理由

TypeError: No to_python (by-value) converter found for C++ type: Base* 

* std :: vectorに含まれていますか?どうすればそれを動作させることができますか?

答えて

3

あなたはBaseWrapper*を指すために使用することができますタイプとしてBase*を登録することでこの問題を解決することができます

class_<BaseWrapper, noncopyable, Base*>("Base") 
     .def("func", pure_virtual(&Base::func)); 

しかし、Baseは、純粋仮想関数を持つことができないことを意味しているようです...

+0

ええ、Base :: func()を純粋ではないものにすると問題が解決します。ありがとう、少なくともこのソリューションです。しかし、既存のAPIを変更しない回避策はありますか? –

+0

問題を解決するのは純粋ではないだけではなく、私が間違っていない限りBaseWrapperのポインタ型として 'Base * 'も登録していますか?おそらく、ポインタ型として純粋仮想メソッドを持つ型を受け入れるようにPythonを強化する方法があります。 – James

+0

はい、私はfunc()を純粋でなく作成してBase * ptrを登録して問題を解決することを意味しました。 Pythonが純粋な仮想を持つ型を受け入れるようにするにはどうすればよいか説明できますか? –

関連する問題