I needed to connect our project in Java to the old library in C. One of the problems was that this library requires the registration of callbacks (callbacks) that it causes in the course of work, and which I would like to implement on the side of Java.
JNI lets you do it all, but it's a chore. There is an excellent JNA library as a replacement for JNI, I wanted to use it.
Unfortunately, the JNA website is now empty - they are moving from server to server, JNA articles do not show an example of callbacks, so I had to tinker a bit to make a working example.
I want to show this example - maybe someone has to.
')
We start from the side C:
my.h
typedef void ; 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; }
Compile:
gcc -c -fPIC -m32 -g my.c -omy.o
gcc -m32 -shared -g my.o -o ./libmy.so |
and put it somewhere where LD_LIBRARY_PATH points
Create an interface for callback and an interface that represents our C library:
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); }
And that's it! No strange signatures or generation of header files familiar from JNI!
This is called like this:
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")); } }
The only thing that is unpleasant, oh, is that there can be only one method in a callback, i.e. if I have ten kolbekov, I need to create (and register!) ten such classes. But you can make one Java class that will contain all of this logic - it will accept one interface with many methods for callbacks and “translate” it into the language of many classes implementing Callback interface
UPD:
Learn user letu4i writes:
I wanted to note that the implementation of JNA is slightly different in different JVMs. For example, in Cassandra there was a bug due to excessive reliance on JNA:
issues.apache.org/jira/browse/CASSANDRA-1760If it is not difficult, add a disclaimer that should be used carefully.
PS A bug manifested on JRockit JVM