インタープリターが C であり、C コンパイラーでビルドされている場合、Python はどのようにして C++ オブジェクトを呼び出すことができますか?
3 に答える
Boost.Python には関数を宣言する特別なマクロがあるextern "C"
ため、Python インタープリターはそれらを呼び出すことができます。ちょっと複雑ですが、詳細についてはBoost のドキュメントを参照してください。
Python は C-API を宣言します ( http://docs.python.org/2/c-api/またはhttp://docs.python.org/3/c-api/を参照)。PyObject
この API は、通常の C 構造体と呼ばれる汎用オブジェクト型を定義します。この構造体は、Python オブジェクトが実行できる (ほぼ) すべてのことを定義します。たとえば、このオブジェクトに対して加算や比較を行ったり、単純に関数のように呼び出したりするとどうなるかなどです。
Python の型はオブジェクトでもある (したがって、C では構造体で表されるPyObject
) ため、新しい型を定義することは、そのような新しいPyObject
構造体を定義するという単純な問題です。メソッドが Python で呼び出されると、インタープリターは呼び出しをこの構造に関連付けられた C 関数に転送します。
与えられた (コンパイルされた) エクステンションが正しいエントリ ポイントを提供し、Python インタープリターがそれをイントロスペクトして利用可能なものを見つけることができる限り (上記のドキュメントで詳細に説明されています)、他のオブジェクトと同様にこれらのオブジェクトを使用できます。通常、プロンプトで使用できるオブジェクト - ところで、まったく同じ C-API を使用して構築されます。import
コンパイル済みの拡張機能で十分です。
Python インタープリターが上記のコンパイルされた拡張機能からどのように呼び出しているかがある程度明確になることを願っています。欠けている唯一のギャップは、C-API が C++ コードを呼び出す方法です。
Boost.Python は、ここで説明されているように、コード内で C エントリ ポイントを宣言することによってこれを行います: C から C++ をエレガントに呼び出します。たとえば を呼び出すたびに、boost::python::class_
python に宣言した型に対してこれが行われ、PyObject
選択した名前でクラスを表す が作成されます。このクラスを呼び出すと.def
、その構造体の内部スロットが埋められ、新しい型のメソッド、演算子、および属性がさらに宣言されます。これらの内部スロットはそれぞれ、同等の C++ 呼び出しのラッパーにすぎない C スタイルの関数を指します。
C++ は、extern "C" 宣言によって C と相互運用できます。