Search code examples
javajava-native-interfacejna

Register callback from Java to C via JNI or JNA


I have a C API which I want to use in a Java application. I am not new to JNI but I don't know if JNA would be the better choice this time. The native function "RegisterCallback" sends periodically updates from another thread by calling the function pointer. How can I register a Java function via JNI/JNA to this native function pointer (void *pFunc)?

typedef unsigned long DWORD;
typedef void* HANDLE;
typedef enum _Type
{
Update,
Result
} TYPE;

DWORD RegisterCallback(HANDLE handle, TYPE type, void *pFunc);

What do you think? JNA or JNI? Example code is very welcome.


Solution

  • This is what it looks like in JNA:

    public interface MyLibrary extends Library { /* StdCallLibrary if using __stdcall__ */
        interface MyCallback extends Callback { /* StdCallCallback if using __stdcall__ */
            void invoke(/* fill your parameters here*/); 
        }
        DWORD RegisterCallback(HANDLE handle, int type, MyCallback callback);
    }
    
    ...
    MyLibrary lib = (MyLibrary)Native.loadLibrary("mylib", MyLibrary.class/*, options*/);
    MyCallback callback = new MyCallback() {
        public void invoke() {
            System.out.println("Success!");
        }
    };
    HANDLE h = ...;
    int type = ...;
    lib.RegisterCallback(h, type, callback);
    ...
    

    Suffice to say the JNI version is quite a bit longer, plus you have a native compile step to account for.