JNA:Javaへのコールバック

JavaのプロジェクトをCの古いライブラリに接続する必要がありました。問題の1つは、このライブラリが作業中に呼び出され、Java側で実装したいコールバックの登録を必要とすることでした。



JNIを使​​用すると、これらすべてを実行できますが、面倒です。 私が使いたかったJNIの代替として素晴らしいJNAライブラリがあります。

残念ながら、JNA Webサイトは空になっています。サーバーからサーバーに移動しているため、JNAの記事にはコールバックが表示されないため、実際の例を作成するために少し手を加える必要がありました。



この例を示したい-誰かがしなければならないかもしれない。



Cから開始:



my.h

typedef void (*callback)(char *, char*); int myfunc(char *); void registerCallback(callback myc);
      
      







my.c

 #include <string.h> #include "my.h" static callback c; int myfunc(char *name) { (*c)("received", name); return strlen(name); } void registerCallback(callback myc) { c = myc; }
      
      







コンパイルします:

  gcc -c -fPIC -m32 -g my.c -omy.o
 gcc -m32 -shared -g my.o -o ./libmy.so 




LD_LIBRARY_PATHが指す場所に配置します



コールバック用のインターフェイスと、Cライブラリを表すインターフェイスを作成します。



MyCallBack.java

 import com.sun.jna.Callback; public class MyCallBack implements Callback { public void callback (String param1, String param2) { System.out.println(param1+" "+param2); } }
      
      







Mylib.java

 import com.sun.jna.Library; public interface MyLib extends Library { int myfunc(String name); void registerCallback(MyCallBack myc); }
      
      







それだけです! JNIでおなじみの奇妙な署名やヘッダーファイルの生成はありません!



次のように呼び出されます。



 import com.sun.jna.Native; public class App { public static void main(String[] args) { MyLib lib = (MyLib) Native.loadLibrary("my", MyLib.class); lib.registerCallback(new MyCallBack()); System.out.println(lib.myfunc("test1")); } }
      
      







唯一不愉快なのは、コールバックに1つのメソッドしか存在できないということです。 10個のコールバックがある場合、10個のそのようなクラスを作成(および登録!)する必要があります。 ただし、このすべてのロジックを含む1つのJavaクラスを作成できます。コールバック用の多くのメソッドを持つ1つのインターフェイスを取り、Callbackインターフェイスを実装する多くのクラスの言語に「変換」します



UPD:

LJユーザーletu4iの書き込み:

JNAの実装はJVMごとにわずかに異なることに注意したかったのです。 例えば、JNAに過度に依存しているため、Cassandraにバグがありました。



issues.apache.org/jira/browse/CASSANDRA-1760



難しくない場合は、慎重に使用する必要がある免責事項を追加してください。

PS JRockit JVMにバグが発生しました




All Articles