pybind11でC++からPythonを呼び出す
pybind11を使って、C++コードをPythonモジュールとしてラップします。
「pybind11でC++からPythonを呼び出す」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。
なぜpybind11なのか
pybind11は、最小限の定型コードでC++コード向けのPythonバインディングを作成できるヘッダーオンリーライブラリです。SciPy、TensorFlowなど、多くのプロジェクトで使用されています。
最小限のモジュール
PYBIND11_MODULEマクロを使うと、1つのファイルだけでPythonモジュールを定義できます。
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int a, int b) { return a + b; }
PYBIND11_MODULE(mymodule, m) {
m.def("add", &add, "Add two integers");
}モジュールのビルド
Python拡張モジュールとしてビルドします。通常はCMakeまたはsetuptoolsを使用します。
# CMake
find_package(pybind11 REQUIRED)
pybind11_add_module(mymodule mymodule.cpp)Pythonから使用する
通常のPythonモジュールと同じようにインポートして使用します。
# Python
import mymodule
print(mymodule.add(2, 3)) # 5クラスを公開する
py::class_を使ってC++クラスをバインドします。コンストラクタ、メソッド、プロパティはすべてPythonの対応する要素にマッピングされます。
class Point {
public:
Point(int x, int y) : x_(x), y_(y) {}
int x() const { return x_; }
int y() const { return y_; }
private:
int x_, y_;
};
PYBIND11_MODULE(geom, m) {
py::class_<Point>(m, "Point")
.def(py::init<int, int>())
.def("x", &Point::x)
.def("y", &Point::y);
}型変換
pybind11は一般的な型を自動的に変換します。
std::string↔ Python strstd::vector<T>↔ Python liststd::map↔ Python dict- 数値 ↔ Python int/float
NumPyとの相互運用
NumPy配列はpy::array_t<T>として渡します。バッファにアクセスすると、コピーなしで操作できます。
void scale(py::array_t<double> arr, double factor) {
auto buf = arr.mutable_unchecked<1>();
for (size_t i = 0; i < buf.size(); ++i)
buf(i) *= factor;
}バインディングとしてのラムダ
引数を変換したり動作をラップしたりする場合は、ラムダを直接バインドします。
m.def("show", [](const Point& p) {
return "(" + std::to_string(p.x()) + ", " + std::to_string(p.y()) + ")";
});GILの解放
時間のかかるC++計算では、GILを解放して他のPythonスレッドを実行できるようにします。
m.def("slow", []() {
py::gil_scoped_release release;
// expensive C++ work, no Python access
});パフォーマンス
pybind11によるオーバーヘッドは最小限で、通常は呼び出しごとに数百ナノ秒です。複雑な関数では無視できる程度ですが、呼び出し先のコストが小さいタイトなループでは影響します。
代替手段
その他のPython-C++ブリッジは次のとおりです。
- Boost.Python — 古く、より重いライブラリです
- SWIG — 多くの言語をサポートします
- nanobind — より新しく、pybind11より高速です
実際のユースケース
pybind11は次の用途に適しています。
- C++ライブラリをPythonユーザー向けにラップする
- C++コードでPythonのホットパスを高速化する
- C++アプリとPythonツールの間で数値計算カーネルを共有する
クイックチェック
pybind11がPythonモジュールの宣言に使用するマクロはどれですか。
まとめ
pybind11を使うと、C++をPython向けにラップする作業がほぼ手間なく行えます。PYBIND11_MODULEでモジュールを宣言し、関数をm.defで、クラスをpy::class_でバインドします。組み込みの変換機能はSTL型に対応し、NumPy配列はコピーなしで扱えます。
よくある質問
「pybind11でC++からPythonを呼び出す」レッスンは無料ですか?
はい。「pybind11でC++からPythonを呼び出す」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。
「pybind11でC++からPythonを呼び出す」で何を学びますか?
pybind11を使って、C++コードをPythonモジュールとしてラップします。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C++ Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「pybind11でC++からPythonを呼び出す」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC++ Academyレッスンでコードを書いて実行できますか?
はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- extern CとC ABI
- pybind11でC++からPythonを呼び出す
- Rust FFI境界向けC++
- SWIGによる多言語バインディング