繁体   English   中英

带有 void * 参数的 JNA 回调 function

[英]JNA Callback function with void * argument

map 以 void* 作为参数的回调 function 的正确方法是什么?

我正在使用 JNA 处理本机库 (.dll)。 库定义了以下回调 function:

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

这是它在 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));
    }
}

我设置回调 function。但是问题在运行时开始。 回调 function 只执行一次,然后 java 应用程序失败,退出值非零 -1073740791。 未生成 hs_err_pid* 日志文件。

映射有问题吗? 我找不到以 void* 作为参数的映射示例。 一般void*被映射为Pointer,当它作为参数时有什么不同吗? 每次回调后都需要释放memory吗? 我试着做Native.free(Pointer.nativeValue(value)); 内部回调,但这并没有解决问题。

PS 我确实阅读了JNA - callback method with void* arguments stackoverflow 问题,但它似乎不是我的情况。 我将回调声明为 static member public static NatLib.NotifyFunc notifyFunction = new MyNotifyFuncImpl(); - 这应该保持对回调 function 的引用不变,而不是在运行时收集垃圾。

问题是您不能使用Callback ,如果它是__stdcall function。在这种情况下,您需要实施StdCallLibrary.StdCallCallback 所以你的代码应该是这样的:

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

这背后的原因是__stdcall用于调用 Win32 API 的函数。如果你只使用Callback Jna 不知道它必须使用这些。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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