简体   繁体   中英

JNA Callback function with void * argument

What is the correct way to map a callback function that has void* as an argument?

I am working with native library (.dll) using JNA. Library defines the following callback function:

typedef void (__stdcall *NotifyFunc)(int code, void *value); .

Here is how it is mapped in java:

public static NatLib.NotifyFunc notifyFunction = new MyNotifyFuncImpl();

public static void main(String[] args) {

    NatLib.INSTANCE.SetCallbackFunc(notifyFunction);
}

public interface NatLib extends Library {

    NatLib INSTANCE = Native.load("Nat.dll", NatLib.class);

    //...

    void SetCallbackFunc(NotifyFunc func);

    interface NotifyFunc extends Callback {
        void MyNotifyFunc(int code, Pointer value);
    }
}

public static class MyNotifyFuncImpl implements NatLib.NotifyFunc {

    @Override
    public void MyNotifyFunc(int code, Pointer value) {
        System.out.println("Notification: " + Integer.toHexString(code));
    }
}

I set the callback function. However problems start at runtime. Callback function is executed only once, and then java application fails with non-zero exit value -1073740791. hs_err_pid* log file is not generated.

Is there something wrong with the mapping? I could not find examples for mappings with void* as parameter. Generally void* is mapped as Pointer, is it different when it is used as a parameter? Do I need to free memory after each callback? I tried to do Native.free(Pointer.nativeValue(value)); inside callback, but this didn't solve the problem.

PS I did read JNA - callback method with void* arguments stackoverflow question, but it doesn't seem to be my case. I declared callback as static member public static NatLib.NotifyFunc notifyFunction = new MyNotifyFuncImpl(); - this should keep the reference to callback function unchanged and not garbage collected during runtime.

The problem is that you can not use Callback , if it is a __stdcall function. In this case you need to implement StdCallLibrary.StdCallCallback . So your code should be like this:

interface NotifyFunc extends StdCallLibrary.StdCallCallback{
    void MyNotifyFunc(int code, Pointer value);
}

The reason behind this is that __stdcall is used to call functions of the Win32 API. And if you only use Callback Jna does not know it has to use these.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM