2

ctypespythonモジュールを使用してpythonからC/C++関数を使用できるようにしたいと思います。

/ファイルに関数int doit()があります。共有ライブラリを読み込もうとすると:.c.cpp

Frr=CDLL("/path/FoCpy2/libFrr.so")
Frr.doit(c_int(5))

.cバリアントを使用すると、非常にうまく機能することがわかります。C ++が呼び出されるとき、この関数を呼び出すための良い方法は次のとおりです(usingをnm libFrr.so使用nm -gC libFrr.soすると、単純に生成されますdoit()):

Frr._Z4doitv(c_int(5))

私はStackexchangeで、PythonからC ++を呼び出す標準的な方法がなく、「非標準の名前マングリング」の問題があることを読みました。「Z4」はその問題の一部ですか?非標準の名前マングリングは、クラスメソッド、テンプレートなどのより高度な言語機能だけでなく、そのような基本的な機能にも現れると思いますか?C ++コードの単純なケースで単純なC関数名を強制的に使用することは可能ですか?

4

2 に答える 2

2

C ++ライブラリ関数の呼び出しは常に混乱します。実際には、C ++を使用している場合でも、同じコンパイラなどを使用して機能するようにする必要があります。

唯一の一般的な解決策は、c ++関数をとして定義しextern "C"、関連する制限に従うようにすることです。その説明については、ここを参照してください。

于 2012-12-14T22:10:57.943 に答える
2

を使用extern "C"して、関数を C 関数のように外の世界に見せることができます (つまり、名前マングリングを無効にします)。はい、あなたは正しいです。名前マングリングは、主にC++が持つより複雑な機能と関数のタイプに必要であり、名前マングリングスキームは標準化されていないため(バイナリ互換性もありません)、コンパイラごとに異なりますおよびバージョン間で(ただし、ほとんどの主流コンパイラは現在、永続的なものに落ち着いていますが、コンパイラベンダー間ではまだ異なります). また、単純な古いフリー関数にもマングリングが必要な理由は、C++ がオーバーロード (同じ関数名でパラメーターが異なる) をサポートしているためです。したがって、コンパイラーはパラメーター指定 (型など) をマングルされた名前にエンコードします。もちろん、使えばextern "C"名前マングリングが必要なすべての機能が失われるため、多かれ少なかれC関数のみに要約されます。

extern "C"次のように、関数ごとにいずれかを使用できます。

extern "C" int doit();

または全体的なヘッダーの場合:

extern "C" {

// all the function declarations here ...

};

ただし、特に Python の場合、C++ のクラスと関数を反映した Python のクラスと関数を作成できるライブラリを使用することを強くお勧めします。これにより、作業が大幅に楽になり、この extern "C" ビジネスがすべて隠されます。 . Boost.Pythonを使用することをお勧めします。この入門ページを参照してください。これにより、関数とクラスを Python に簡単にエクスポートできます。他の人もSWIGを推奨していると思いますが、私はそれを使用したことがありません。

于 2012-12-14T22:35:02.660 に答える