2

多くのクラスを使用する C++ プロジェクトがあります。主なクラスは ' sso::Object' (すべてのクラスは 'sso' 名前空間にあります) で、このクラスは他のいくつかのクラスに派生しますが、抽象クラスは ' sso::Drawable' です。

sso::Drawable::set_opacityこのクラスには ' ' と ' ' の2 つの純粋仮想メソッドがあり、これら 2 つのメソッドを実装するsso::Drawable::raw_draw' ' などの他のクラスに派生します。sso::View

C++ で使用するとプロジェクト全体が正常に動作しますが、Python でも使用したいので、次のような Boost.Python モジュールを作成しました。

class DrawableWrapper : public sso::Drawable , public wrapper<sso::Drawable> {
public:
    void set_opacity(byte opacity) { this->get_override("set_opacity")(opacity); }

    void raw_draw(const sso::Rect &rect,sso::Target &target,const sso::Position &position) const {
        this->get_override("raw_draw")(rect,target,position);
    }
};

BOOST_PYTHON_MODULE(sso) {

    class_<DrawableWrapper,boost::noncopyable> ("Drawable",init<>())
        .add_property ("opacity",&sso::Drawable::get_opacity)
        // python_sso_getter & python_sso_setter_* are only used for an easier access to accessors
        .add_property ("position",python_sso_getter<sso::Drawable,sso::Position,&sso::Drawable::get_position>,python_sso_setter_1_const<sso::Drawable,sso::Position,&sso::Drawable::set_position>)
        .def("raw_draw",pure_virtual(&sso::Drawable::raw_draw))
   ;

    class_<sso::View,bases<sso::Drawable> >                 ("View",init<>())
        .def("insert",python_sso_setter_1<sso::View,sso::Drawable*,&sso::View::insert>)
        .def("remove",&sso::View::erase)
    ;

}

このコードはエラーなしでコンパイルされますが、Python でこれらの行を実行すると:

myview = sso.View()
print myview

私はこの出力を得る:

<0x7f9d2681a4b0 の sso.View オブジェクト>

しかし、私の C++ デバッガーは、変数 'v' (python 'myview') は ' sso::Object' インスタンスであり、' ' インスタンスではないことを教えてくれますsso::Viewsso::View::View()が呼び出されますが、変数の型はビューではなく、理由がわかりません。それについて何か考えはありますか?あなたはそのようなことをして、それを機能させる方法を見つけましたか?

私は Python2.7 と Boost.Python1.49 と gcc バージョン 4.6.1 を使用しています

編集: 私は間違いを犯しました:sso::Drawableは から継承しませんsso::Objectが、sso::View(=多重継承) は継承します。

4

1 に答える 1

1

python からの出力<sso.View object at 0x7f9d2681a4b0>は、オブジェクト タイプが何と呼ばれているかを示す python に過ぎず、C++ レベルで作成されたオブジェクトの実際のタイプとは何の関係もありません。

ブースト python にオブジェクトを公開するように指示したように、sso.Viewそれは python がそれをどのように見るかです。コードを公開するように変更した場合std::stringsso.ViewPython は<sso.View object at 0x7f9d2681a4b0>作成後も報告します。

同様に、"View"C++ を に変更した場合"BlahDeBlah"、Python はオブジェクトを次のように報告します<sso.BlahDeBlah object at 0x7f9d2681a4b0>(もちろん、次のように作成する必要もあります)。sso.BlahDeBlah()

それはさておき、あなたが投稿したコードに問題はありません。sso::Viewから継承しsso::Objectますか? その場合、sso::view::View()呼び出されているのを目撃したことがある場合は、デバッガーがオブジェクトのタイプがsso::Object. おそらく、デバッグしている時点で、基本クラスまたは同様のものへのポインタがありますか?

myview.insertpython から呼び出したとき、またはpython から呼び出したときはどうなりますmyview.removeか?

編集: コンパイラで RTTI がオンになっていない可能性があると思われます (間違っている可能性がありますtypeid()) typeid()。それは確かになぜあなたがsso::Viewいつ入るのかを説明するでしょうinsertが、他の機能では別の答えになります.

とにかく、私はドキュメントをもう少し調べてきましたが、あなたの問題は実際にはraw_drawメソッドをオーバーライドする機能を提供したが、実際には何もオーバーライドしていないことだと思います。

このファイルの下部にpure_virtualあるboost::python 関数の宣言を見ると、次のコメントが表示されます。

//
// Passed a pointer to member function, generates a def_visitor which
// creates a method that only dispatches to Python if the function has
// been overridden, either in C++ or in Python, raising a "pure
// virtual called" exception otherwise.
//

したがって、あなたが見ているのは、予想される動作です。raw_drawinまたはそれを継承する python クラスのオーバーライドを提供すると、sso::Viewこのエラーは発生しなくなります。

于 2012-07-03T10:57:46.327 に答える