Jython を使用して GUI を作成しています。C でロジックをプログラムしたいのですが、Python コードから C 関数を呼び出すにはどうすればよいでしょうか。これが初心者の質問である場合は申し訳ありませんが、C からの Sparc アセンブリ以外のファイルをリンクする作業をしたことがありません。
2 に答える
Jython はctypes
、または C 拡張モジュールを使用できません (手動で構築されたか、Cython で構築されたか、またはその他の方法で構築されたかに関係なく)。
これを行う方法は、Java の場合と同じで、JNI ブリッジを使用します。
最初に、so と対話する C++ ラッパーを作成し、関数を使用して次の<jni.h>
ような関数を実装します。
JNIEXPORT void JNICALL _PACKAGE(bar)(JNIEnv *env, jclass cls, jint i) {
if (bar(i)) {
throwPyFromErrno(env, OSError);
}
}
次に、Java で、次のpublic
ように、これらの C++ ラッパーの周りに Java ラッパーでいっぱいのクラスを定義します。
public class foo implements InitModule {
public final static native void bar(int i);
}
最後に、Jython では、Java モジュールからクラス (Python モジュールのように機能する) をインポートするだけで、他のモジュールと同じように使用できます。
try:
foo.bar(3)
except OSError as e:
print "Failed:", e
これのほとんどは標準の JNI ですが、Jython オブジェクトの作成方法なども知っておく必要があります。理想的には、そのためにラッパーを使用するので、手動ですべての 、 などを行う代わりにmakePyInteger(env, value)
orを書くことができます。throwPyFromErrno(env, exctype)
FindClass
GetStaticMethodID
推奨するチュートリアルはありません。ただし、適切なサイズの例についてはjniosを参照してください。The O'Reilly book's Chapter 25. Extending and Embedding Jython (Jython の拡張と埋め込み) はまともな入門書のように思えます (私はまだ読んでいませんが)。Jython に取り組む前に、JNI for Java の使用に関するチュートリアルを読むことをお勧めします。
この問題を解決する別の方法は、1 つのプログラムを 2 つの部分に分割することです。
GUI プログラムは Jython で実行されます。C コードを呼び出す必要がある場合は、ワーカー プログラムを実行して行います。
ワーカープログラムはCPythonまたはPyPy で実行されるため、C ライブラリと対話するためのctypes
通常cffi
の手法を使用できます。 .
1 つの関数を呼び出し、それにいくつかの文字列を渡し、文字列を取得するだけの単純なケースでは、次のように簡単です。
import subprocess
def my_function(*args):
return subprocess.check_output(['python',
'/path/to/worker/script.py'] + args)
(特に OS X と Windows では、古いバージョンの Jython にはいくつかのバグがあることに注意してくださいsubprocess
。問題が発生した場合、現在それぞれ RC 段階とベータ段階にある 2.5.4 と 2.7.0 はおそらく修正しました。)
プログラムの存続期間中に一度に 1 つずつ多くの呼び出しを行う必要がある場合は、ワーカー スクリプトをバックグラウンドで実行し続け、何らかの形式の RPC を使用して対話することをお勧めします。このブログ投稿bjsonrpc
では、ライブラリを使用してそれを行う方法を示します。