2

私の C++ コードには、Bar 型の変数を引数として取る多くのメソッドを持つクラス Foo があります。

class Foo {
public:
  void do_this(Bar b);
  void do_that(Bar b);
  /* ... */
};

Bar には、int、std::string、float などの多くの一般的な型から新しいオブジェクトを作成するコンストラクタがいくつかあります。

class Bar {
public:
  Bar(int i);
  Bar(float f);
  Bar(std::string s);
  /* ... */
};

これを Boost::Python でラップし、暗黙的に Bar オブジェクトに変換されるため、Python リテラルを直接使用して Foo メソッドを呼び出すことができるようになりました。

f = Foo()
f.do_this(5)
f.do_that("hello")

ここで、次のように、タプルなどの他の Python タイプも使用できるようにしたいと考えています。

f.do_that((1,2,3))

しかし、元の Bar 定義には触れたくありません。また、私の C++ ライブラリを Boost::Python のもので汚したくありません。バインディング コードにラッパー関数を記述したいのですが、これが可能かどうか、およびこれを行う正しい方法がわかりません。

つまり、Python で自動変換として使用するファクトリ関数を登録できますか?

4

6 に答える 6

2

Subclass Bar near the wrapper code and give your subclass a ctor that takes a bp::object (or a more specific python type)

struct Bar_wrapper:Bar,bp::wrapper<Bar>
{
    Bar_wrapper(bp::object arg)
    {
        //code to build a Bar_wrapper Here
    }
}

Then export a Bar_wrapper to python instead of a Bar, and call it a Bar as the python name:

class<Bar_wrapper>("Bar")
    ...
    .def(init<bp::object>())
    ...
于 2010-11-09T19:46:57.880 に答える
1

template <typename T> Bar(T) ヘッダーに新しいコンストラクターを追加し、次のように実装しますtemplate <> Bar::Bar(Tupple) {}

于 2011-09-13T12:07:38.920 に答える
0

Barfrom-任意のオブジェクトからインスタンスを構築するPythonコンバーターを登録できます。ここと私自身の例((Vector3,Quaternion)タプルまたは7 *ダブルタプルのいずれかを3D変換に変換するSe3)をここで参照してください。

ロジックには2つのステップがあることに注意してください。最初に、オブジェクトが変換可能かどうかを判断し(convertible;この場合、オブジェクトがシーケンスであり、適切な数の要素があることを確認します)、次にconstructメソッドが呼び出され、実際にインスタンスが返されます。 、パラメータとして渡されたポインタで割り当てられます。

次に、コンバータをに登録する必要がありますBOOST_PYTHON_MODULE。コンバータレジストリはグローバルであるため、登録されると、その後はどこでも自動的に使用されます。タイプのすべての関数の引数、Barまたは問題なく処理する必要があります(頭のてっぺんからconst Bar&もわかりません)。Bar&

于 2011-09-13T14:12:13.910 に答える
0

静的ファクトリ メソッドを作成し、それをクラスの Python コンストラクタの 1 つとして公開できます。任意の Python オブジェクトを受け取るコンバーターを作成するだけで、好きなことを自由に行うことができます。

using namespace boost::python;

Bar CreateBar(object obj)
{
    // Do your thing here

    return Bar;
}

// ..................

class_<Bar>("Bar")
    // .....................
    .def("__init__", make_constructor(&CreateBar))
    //.............
    ;
于 2011-09-13T13:38:43.080 に答える
0

オーバーライドされた「operator ,(int)」でいくつかのタイプ TupleCollector を作成して、次のように記述できるようにします。

f.do_that((TuppleCollector(), 1, 2, 3))

最後に、TupleCollector と期待されるターゲットの間の変換を作成します

于 2009-08-10T10:03:26.313 に答える
-1

boost::python::object パラメーターを受け取る関数 do_that をエクスポートし、param が python タプルであるかどうかを確認し、データを抽出してオブジェクトに渡すことができます。

于 2009-12-11T11:21:35.227 に答える