简体   繁体   English

有没有办法强制 Java VM 立即执行从 JNI 发送的异常?

[英]Is there a way to force Java VM to execute immediately an exception sent from JNI?

I need to send an exception in Java from the main jni-thread.我需要从主 jni 线程在 Java 中发送一个异常。 I use the following code to do such a thing:我使用以下代码来做这样的事情:

if (vm->AttachCurrentThread(reinterpret_cast<void **>(&env), nullptr) != JNI_OK || env == nullptr) {
    std::cerr << "Get env for current thread failed.\n";
    return ;
}
jclass exClass = env->FindClass("[JavaClassName]");
if (exClass != nullptr) {
    env->ThrowNew(exClass, "[ExceptionMessage]");
}
env->DeleteLocalRef(exClass);
vm->DetachCurrentThread();

It somehow works.它以某种方式起作用。 I have found out that if we don't use the attach and detach (just use only the throw) then the exception raises only after the jni-call from Java VM is finished.我发现如果我们不使用附加和分离(只使用抛出),那么只有在来自 Java VM 的 jni 调用完成后才会引发异常。 If we use the attach and detach then the exception raises in the detach call.如果我们使用附加和分离,那么在分离调用中会引发异常。 Is it a correct way to make things faster?这是使事情更快的正确方法吗? I don't still understand why the exception processing is deferred until a call to DetachCurrentThread()?我仍然不明白为什么将异常处理推迟到调用 DetachCurrentThread() 之前? I use Android.我使用 Android。 Thank you very much.非常感谢。

The Java interpreter attached to your current thread is not running whilst you are in the JNI code.当您在 JNI 代码中时,附加到当前线程的 Java 解释器未运行。 So there is no way to process the exception on the Java side (unwind stack frames, catch etc).所以没有办法处理 Java 端的异常(展开堆栈帧,catch 等)。 The Java exception is created as pending and only really thrown when the JNI call returns to Java and the execution of the interpreter continues for your current Java thread. Java 异常被创建为挂起,并且仅在 JNI 调用返回到 Java 并且解释器继续为您当前的 ZD52387880E1EA22817A72D3759213819 线程执行时才真正抛出。

Detaching sort of fakes this process but could leave your JNI code in an unstable state: Java is now running, JNI has not returned and is still running your code.在此过程中分离假货,但可能会使您的 JNI 代码处于不稳定的 state 中:Java 现在正在运行,JNI 尚未返回并且仍在运行您的代码。

My preferred solution is to throw the Java exception as you do and immediately throw a C++ exception which is only (and must be) caught at the JNI boundary and discarded.我的首选解决方案是像您一样抛出 Java 异常,然后立即抛出 C++ 异常,该异常仅(并且必须)在 JNI 边界处捕获并丢弃。 The C++ exception is thrown purely to cause stack unwinding and a quick clean exit from the JNI call.抛出 C++ 异常纯粹是为了导致堆栈展开和从 JNI 调用中快速干净退出。

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

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