4

私は C++/Python 混合言語プログラミングに不慣れで、Python/C API についてあまり知りません。Boost.Python を使用して、Python 用の C++ ライブラリをラップし始めました。配列へのポインタを引数として取る関数のラップに行き詰まっています。以下 (2 番目の ctor) は C++ でのプロトタイプです。

class AAF{
  AAF(AAF_TYPE t);
  AAF(double v0, const double * t1, const unsigned * t2, unsigned T);
  ~AAF();
}

このようにboost::pythonでラップすることで、私は正しくやっていますか?

class_<AAF>("AAF", init<AAF_TYPE>())
  .def(init<double, const double*, const unsigned*, unsigned>());

コンパイルとリンクは成功しましたが、Python で呼び出す方法がわかりませんでした。次のような私の素朴な試みは失敗しました。

>>> z = AAF(10, [4, 5.5, 10], [1, 1, 2], 3);

Traceback (most recent call last):
  File "./test_interval.py", line 40, in <module>
    z = AAF(10, [4, 5.5, 10], [1, 1, 2], 3);
Boost.Python.ArgumentError: Python argument types in
    AAF.__init__(AAF, int, list, list, int)
did not match C++ signature:
    __init__(_object*, AAF_TYPE)
    __init__(_object*, double, double const*, unsigned int const*, unsigned int)

>>> t1 = array.array('d', [4, 5.5, 10])
>>> t2 = array.array('I', [1, 1, 2])
>>> z = AAF(10, t1, t2, 3);

Traceback (most recent call last):
  File "./test_interval.py", line 40, in <module>
    z = AAF(10, t1, t2, 3);
Boost.Python.ArgumentError: Python argument types in
    AAF.__init__(AAF, int, array.array, array.array, int)
did not match C++ signature:
    __init__(_object*, AAF_TYPE)
    __init__(_object*, double, double const*, unsigned int const*, unsigned int)

2 番目の質問は、デストラクタもラップする必要があるかということです。場合によってはこれが必要になるかどうかを指定してください。ただし、常にではありません。

4

1 に答える 1

4

ラッピングは(原則として)正しいですが、

AAF(10, [4, 5.5, 10], [1, 1, 2], 3);

(インタプリタが指摘しているように)ポインタではなく、関数pythonのリストオブジェクトに渡しています。

つまり、関数がPythonのリストでのみ機能する必要がある場合は、(ポインターを使用する代わりに)そのインターフェイスを使用するようにコードを変更する必要があります。そのインターフェースを維持する必要がある場合は、Pythonからリストを取得し、適切な変換を行い、元のc++関数を呼び出すラッパー関数を作成する必要があります。同じことがnumpy配列にも当てはまります。

boost :: pythonには、pythonコンテナをstl互換コンテナに変換するための組み込みメカニズムが用意されていることに注意してください。

ケースのラッピングコードの例は次のとおりです。

void f(list o) {
    std::size_t n = len(o);
    double* tmp = new double[n];
    for (int i = 0; i < n; i++) {
        tmp[i] = extract<double>(o[i]);
    }
    std::cout << std::endl;
    // use tmp
    delete tmp;
}

http://www.boost.org/doc/libs/1_39_0/libs/python/doc/tutorial/doc/html/index.htmlでboost.pythonチュートリアルをご覧ください。

于 2009-06-02T17:22:33.597 に答える