Cythonを使用して、PythonコードでC++グローバル変数にアクセスしようとしています。
C++コードに次の配列があるとします。
// Project.cpp
int myArr[2] = { 0, 1 };
したがって、CythonでmyArrへのポインタを定義するには:
cdef extern int * myArr_ptr
myArr_ptrは本当にC++配列を指していますか?それとも単なるランダムな値ですか?
Cythonを使用して、PythonコードでC++グローバル変数にアクセスしようとしています。
C++コードに次の配列があるとします。
// Project.cpp
int myArr[2] = { 0, 1 };
したがって、CythonでmyArrへのポインタを定義するには:
cdef extern int * myArr_ptr
myArr_ptrは本当にC++配列を指していますか?それとも単なるランダムな値ですか?
OK、問題は次のとおりです。
Project.cpp
グローバルがありint *myArr;
、にリストされていProject.h
ないため、インポートせずにCythonからアクセスしたいProject.cpp
。
コメントで、あなたは言います:
Project.cppを含めることはできません。これは、このファイルがすでに含まれている他のファイルを含めようとし、多くの変数を再定義しようとするためです。
あなたがそれを説明したように、ここに初歩的ミスがあるかもしれません。あなたはおそらくこれらの基本的なことを知っているので、私がそれらを育てることに侮辱されないでください、しかし私はただ徹底したいです:
まず、ヘッダーファイルに複数のインクルードに対するガードがない場合は、それを修正します。そうすれば、「Project.cpp
このファイルはすでにインクルードされている他のファイルをインクルードしようとするため、インクルードできません。多くの変数を再定義します。」(そして、ヘッダーファイルがなく、.cppファイル内のすべてを明示的なextern
ステートメントですべての場所で実行している場合は、それを実行しないでください。CおよびC ++では、 Cythonizing。)
次に、モジュールがProject.cpp
の一部である.so / .dll / .dylibにインターフェイスすることを目的としている場合は、そのライブラリのソースに対してビルドするのではなく、インストールされているインターフェイスに対してビルドする必要があります。一方、モジュールにC ++コードを直接含める場合は、を含める必要がありますProject.cpp
。リンクインしないものを参照するために宣言を使用するextern
と、リンカーエラーが発生するだけです。または、運が悪ければ、すべてがビルドされますが、実行時に失敗します。
第3に、実際にグローバルでない場合、外部からアクセスすることはできません。Project.cpp
スコープ、存続期間、またはリンクの理由から、別の実装ファイルで他の種類の変数を使用することはできません。
繰り返しますが、私はあなたがそれらの基本的なことをすべて知っていると思います、そして私はあなたのコメントを読み間違えました。内部に到達する必要がある、設計が不十分なAPIで何かをラップする必要があるという実際の問題のケースがあります。これは時々注意が必要ですが、おそらくそのようなことに遭遇しましたが、私はまだそうしていません。正確な方法を理解しました。
3つの基本的な解決策があります。
まず、明らかに、適切なネイティブAPIを構築できる場合、そのAPIをCythonでラップするのは簡単です。そして、これは同時に他の理由でも役立ちます。場合によっては、これは時間と労力がかかりすぎることがあります。たとえば、ネイティブライブラリが外部で駆動されるように設計されておらず、10年間のレガシーメンテナンスの大部分であり、ラップしなければならない唯一の理由である場合などです。これは現在のCythonプロジェクトであるため、クリーンアップしたくない場合があります。または、最新の状態に保つ必要があり、ソース管理ができない、急速に変化するライブラリの場合、それをフォークして同期を維持しようとすることは悪夢になる可能性があります。等々。しかし、あなたの場合にそのような理由がなければ、これは正しい答えです。できればcdef extern from "project.h"
、すべてが簡単です。
ネイティブレベルで「shimAPI」を作成し.h
、内部から使用する必要のあるさまざまな関数と型に適切なextern、関数、および型宣言を使用して個別のファイルを作成することで、より単純なバージョンを実行できます。次に、あなたはただすることができますcdef extern from "project_extras.h"
。
最後に、cdef extern
Cythonにどこから来たのかを言わなくても、いつでも明示的なステートメントを書くことができます。Cythonは、生成されたコードでこれを適切なネイティブexternに変換し、すべてが正しく行われれば機能します。ここにはいくつかの欠点があります— <ahref="http://docs.cython.org/src/userguide/external_C_code.html#referencing-c-header-files"rel="nofollow">ドキュメントはcdef extern from
あなたはあきらめるでしょう。短いバージョンでは、Cython宣言はネイティブ宣言と正確に一致する必要があります。そうしないと、Cythonの段階で自動的に修正されたり、適切なエラーが発生したりする代わりに、実際のコードではなく、読み取り不可能なCythonで生成されたCコード、またはさらに悪いことに、コードを参照する不可解なエラーメッセージがCコンパイラから表示されます。それはコンパイルされますが、間違ったことをします。
単純int *
またはint []
値の場合、解釈を必要としないため、これらすべてはほとんど問題になりません。平野cdef extern
はちょうどいいはずです。