环境->;JNA中的ExceptionCheck()

环境->;JNA中的ExceptionCheck(),jna,Jna,我在我的项目中使用JNA,我的Java JNA回调在某些情况下会抛出异常。我想从C/C++代码中知道上次calbback方法调用引发了一个异常。在JNI中,可以使用env->ExceptionCheck()来完成,但在JNA中找不到任何等价物 有可能实现这一点吗?调用回调的本机代码当然不希望引发Java异常。不能保证JNA回调将从包含JVM的上下文中调用。即使是这样,您也必须建立带外通道,以便将异常从回调传递到堆栈更上层的JVM,因为您无法保证调用C代码 假设您有Java代码->C代码->回调,

我在我的项目中使用JNA,我的Java JNA回调在某些情况下会抛出异常。我想从C/C++代码中知道上次calbback方法调用引发了一个异常。在JNI中,可以使用env->ExceptionCheck()来完成,但在JNA中找不到任何等价物


有可能实现这一点吗?

调用回调的本机代码当然不希望引发Java异常。不能保证JNA回调将从包含JVM的上下文中调用。即使是这样,您也必须建立带外通道,以便将异常从回调传递到堆栈更上层的JVM,因为您无法保证调用C代码

假设您有Java代码->C代码->回调,我建议您捕获所有回调的异常,然后将它们放在某个地方,以便调用Java代码在调用后进行检查

您可以使用
InvocationMapper
在幕后实现这一点,它基本上可以让您捕获和/或修改接口映射调用的结果,但可能更简单的方法是明确说明它,并将整个过程包装在实用函数中

例如:

public interface MyLibrary extends Library {
    MyLibrary INSTANCE = (MyLibrary)Native.loadLibrary();
    interface MyCallback extends Callback {
        void invoke();
    }
    void myFunction(MyCallback callback);
}
然后提供一个实用程序包装器:

public void myFunction(final MyCallback callback) {
    final List<Exception> exceptions = new List<Exception>();
    MyLibrary.INSTANCE.myFunction(new MyCallback() {
        public void invoke() {
            try {
                callback.invoke();
            } catch(Exception e) {
                exceptions.add(e);
            }
        }
    });
    if (exceptions.size() > 0) {
        // ...
    }
}
public void myFunction(最终MyCallback){
最终列表例外=新列表();
MyLibrary.INSTANCE.myFunction(新的MyCallback(){
公共无效调用(){
试一试{
callback.invoke();
}捕获(例外e){
例外情况。添加(e);
}
}
});
如果(异常.size()>0){
// ...
}
}

我查看了callback.c,发现它在方法调用(*env)->ExceptionClear(env)之后清除异常