2

SWIGでこれをややエレガントにするのに苦労しています...

オーバーロードされたメソッドcreateを含む基本クラスがあります。

class Base {
public:
    virtual Foo *create(ClassA &, ClassB &) = 0;
    Foo *create(int id) {
        // get ClassA a and ClassB b from an internal store related to id
        return create(a, b);
    }
};

もちろん、これは面倒なことなくSWIGでラップされています。

他の場所/リポジトリには、Baseのいくつかの異なる派生クラスがあり、もちろん、純粋な仮想create(ClassA&、ClassB&)メソッドの独自のバージョンを定義しますが、create(int)バリアントを定義する必要はありません。基本クラスバージョンで十分です。

これらの派生クラスのSWIGラッピングは、派生クラスで定義されたcreate()メソッドのみを参照し、基本クラスから継承する必要がある場合でも、単一のintパラメーターを持つバリアントを提供しません。

基本クラスのメソッドに%renameを使用して、機能するものを取得しようとしました。

%rename (_create1) Base::create(ClassA&,ClassB&);
%rename (_create2) Base::create(int);

%extend (Base) {
    %pythoncode {
        def create(self, a_or_id, b=None):
            if b is not None:
                self._create1(a_or_id, b):
            else:
                self._create2(a_or_id)
    }
}

これは、生成されたpython / _wrap.ccコードでは問題ないように見えますが、派生クラスのラッパーは、%renamesがないかのようにcreate()メソッドをラップするだけです。

これら別々の.iファイルにありますが、派生クラスの.iファイルはそれぞれbaseclasses .iファイルをインポートするため、Pythonクラスの継承は正しく、このオーバーライドされたメソッドによっていくらか無効になるのはC++クラスの継承だけです。

理想的には、すべての派生クラスの.iファイルに%renameステートメントを挿入する必要がないソリューションが必要です(これで問題が解決することはわかっていますが)、重複したコードが非常に多いことを意味します。

何か案は?

4

1 に答える 1

3

クラスが正しく宣言されていることを確認しますか?using派生クラスの同じ名前の仮想メソッドは、基本関数を派生名前空間に持ってこない限り、基本クラスのメソッドを非表示にします。例:

class A
{
    public:
        void func(int a);
        virtual void func(int a,int b);
};

class  B : public A
{
    public:
        //using A::func;
        virtual void func(int a,int b);
};

SWIGとPythonでは、次のように書くことができませんでした。

b = B()
b.func(1)    # failed
b.func(1,2)

上記の行のコメントを外さずusingに、クラスはC++でも正しく機能しませんでした。を使用するusingと、SWIGは関数をPythonに正しく公開し、C++も機能しました。

于 2012-11-23T23:35:18.453 に答える