18

プログラムで python (CPython) を使用して、自分の環境でユーザー スクリプトを許可し、pyside (c++ の qt バインディング) を使用してアプリケーションの GUI を作成できるようにすることを検討しています。これらは、GUI python コードを後でコンパイルして高速化できるという考えで効果的に分離できます (可能であれば)。

私はPythonを初めて使用し、プロジェクトが進化するにつれてバインディングが頻繁に変更される可能性があるため、維持する追加コードを最小限に抑えて確実なバインディングを生成する最も効率的な方法を本当に探しています。Python クラスが仮想を持つ C++ クラスを拡張するために必要です。

私はすでにPyBindGenを調べましたが、ライブラリ内のものを頻繁に詰まらせるため、実際には役に立ちません。

この点に関してあなたが推奨するヘルプ/アドバイス/リンク/ワークフローは非常に役に立ちます。

4

6 に答える 6

16

C++ 用の自動バインド ジェネレーターがあると私が知っているプロジェクトは 2 つだけです。1つ目はSWIGです。他の回答がすでに述べているように、少し古いスタイルですが、機能します。2 つ目は Boost.Python です。それ自体ではバインディングを自動的に生成しませんが、Boost.Pysteを使用してそれを行うことができます。元のソース コードを解析し、Boost.Python バインディングを記述するには、GCC-XML が必要です。どちらのオプションも、Python からオーバーロードできる C++ の仮想メソッドをサポートしています。

とは言っても、通常、バインドするときに、C++ にあるすべてのものを盲目的に Python にバインドすることはありません。このようにすると、Python 側から非常に Pythonic な感覚を得ることはありません。代わりに、ライブラリを Python でどのように使用するかを、可能な限り最も Pythonic な方法で設計してから、戻って、可能なバインディング ライブラリの 1 つを使用して C++ コードにパッチを適用する方法を確認します。たとえば、 を処理する代わりにstd::vector、ライブラリ呼び出しで Python リストまたは iterable を処理することをお勧めします。C++ ライブラリが を受け取る場合、std::mapそれを Python 辞書で処理する必要があります。配列の場合は、 a のnumpy.ndarray方が便利かもしれません。等々...

そうは言っても、メンテナンスを最小限に抑えるようにバインディングを設計することはできます。

他の Python/C++ ラッピングのリストを次に示します。

  1. SWIG - ご存じのとおり
  2. Boost.Python - これは私たちが通常ここで使用するものです - かなりよく構造化されています
  3. Cython - Python に近い非常にきちんとした構文 - Boost.Python よりもはるかに高速であると主張しています
  4. SIP - あまり普及していませんが、存在します
  5. pybind11 - Boost.Python に似た構文, C++11 のおかげでコンパクトな実装.

これらは現在非アクティブです:

  1. PyBindGen - 最速であると主張していますが、2017 年 5 月 21 日、2014 年の以前のリリース以降は非アクティブです - 現在 github で維持されています ( https://github.com/gjcarneiro/pybindgen/releases )
  2. ECS:Python - 2014 年 12 月 6 日 (v2.8) 以降非アクティブ、github に移動 ( https://github.com/MarcusTomlinson/ECS-Python )
  3. PyCXX - Python 拡張機能の記述を容易にする C++ 機能 -非アクティブ? 最終リリースは 2017 年 4 月 23 日の v7.0.2 でした
  4. CLIF - CLIF は、さまざまな言語用の C++ ラッパー ジェネレーターを作成するための共通の基盤を提供します -非アクティブですか? リポジトリでのアクティビティはあまりありません (コミットは 14 件のみ)

完全を期すために、正式なバインディングを作成せずに、コンパイルされた C コードを Python に直接ロードすることもできます。 これは、次の 2 つの Python モジュールのいずれかでFFIを使用して行うことができます。

  1. ctypes - これは Python にネイティブであり、外部モジュールのインストールは必要ありません。
  2. cffi - これは、Lua JIT の同等の設計に触発された新しいパッケージです。
于 2013-08-05T07:54:01.507 に答える
2

速度を求めるなら、私も間違いなく Cython に投票します。C++ と Python をインターフェースする他の方法について私が知る限り、「ワークフローの流動性」の向上に関して、Cython は他のバインディング ツールと比較して維持/更新がそれほど重くありません。(Cython 化されたコードは、純粋な C と同じか、それほど遠くないと主張しており、非常に興味深いものです)。

とにかく、Python コードを C++ に接続するための優れた API がいくつかあります (Boost.Python など)。間違っているか、不正確です)。

一方、Cython では、C++ API (GUI など) を公開ソース (いわゆる .pyx 拡張子) から厳密に分離しておくことができます。最終的なワークフローは次のようになります。

C++ API => 共有オブジェクトとしてのコンパイル => Cython 拡張機能 (C++ 機能のインポートと公開) => 拡張機能のコンパイル => 拡張機能の使用 (Python パスに追加される拡張機能)。

良いニュースは、進化する C++ 機能に関連する .pyx ファイルのプールの変更部分 (公開する必要がある部分) のみを維持する必要があることです。最初は投資のようなものですが、私の経験では、このワークフローがセットアップされると、全体を複​​雑に成長させるのは非常に簡単です.

バーチャルを持つクラスを拡張し、Python からそれらをオーバーライドする必要性について (私があなたの意図を正しく理解した場合)。それは実行可能です。繰り返しますが、それほど直接的ではありませんが、このスレッドをご覧ください。

悪いニュース: その特定のケースでは、拡張された python が指定された親のメソッドをオーバーライドしない場合に親メソッドの呼び出しを有効にするために、いくつかの追加の C++ アダプター/インターフェイスを作成する必要があります。(仮想であるかどうかにかかわらず、C++ で公開されたメソッドを python から再定義することは、関数の置き換えですが、オーバーライドとはまったく同等ではないことに注意してください)。

うーん、自分自身を読み返してみると、少し混乱しているように見えます。これがまだ役立つことを願っています。

Cythonオプションを選択した場合に対処する必要があるワークフローについて、より具体的に説明できますが、上記のスレッドは非常に良い出発点だと思います...

于 2012-12-25T04:19:15.123 に答える
0

SWIGはやりたいことができる素晴らしいツールです

http://sourceforge.net/projects/swig/

于 2013-08-05T08:10:48.427 に答える
0

AFAICT、C ++にはそれほど多くのオプションはありません。古いプロジェクトの 1 つにSWIGがあります。少し難解で扱いにくいと報告されていますが、長い間存在しているため、他のプロジェクトでは処理されない多くのこともカバーする必要があります。Cythonも参照してください。

于 2012-12-21T12:40:53.267 に答える