JNI int 方法从异常返回

foe*_*ens 2 java-native-interface exception jint android-ndk

假设我有一个这样的 Java 类:

    public class Test
    {
        static { System.loadLibrary("test"); }
        public native int foo();
    }
Run Code Online (Sandbox Code Playgroud)

假设 foo() 方法正在执行一些 JNI 调用,并且其中一个调用失败(IE,抛出异常)。然后我想从 JNI 代码返回并在 Java 中抛出异常。例如:

    jint Java_Test_foo(JNIEnv* env, jobject thiz)
    {
        jstring foobar = (*env)->NewStringUTF(env, "Hello from JNI !");
        if(foobar == NULL) // Not enough memory. OutOfMemoryError is thrown
            return NULL; // Return immediately to get exception thrown in Java
        // Do other stuff
        ...
        return some_computed_jint;
    }
Run Code Online (Sandbox Code Playgroud)

问题是这return NULL不是一个吉特。例如,在 Android 中,我在编译时会收到此警告: warning: return Makes Integer from Pointer without a Cast

现在的问题是:如果在返回 jint 的 JNI 方法中抛出异常,我应该返回什么?

Edw*_*son 6

如果你的代码(或库)Exception在 Java 中引发了 ,那么无论你返回什么值,Java 都会忽略它。显然它需要是兼容的类型 - 所以0在你的例子中返回似乎是有意义的,或者任何你喜欢的类型。当您的代码返回时,Java 运行时将注意到Exception已引发 an 并继续传播它并忽略函数的返回值。

当然,您需要返回兼容的类型。不要简单地 return NULL,因为当函数未声明为返回指针时,它将被int强制转换为 an ,这可能不合适。

但显然,当您调用 C 函数时,这些函数不会引发Exception. 因此,您可以将整数映射到错误条件(-1例如),然后Exception在 Java 中抛出,或者您可以花时间Exception在 JNI 中构建一个。