JNI int 方法从异常返回
假设我有一个像这样的 Java 类:
public class Test
{
static { System.loadLibrary("test"); }
public native int foo();
}
假设 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;
}
问题是 return NULL
不是 jint。以 Android 为例,我在编译时会收到此警告: 警告:返回从指针生成整数,无需强制转换。
现在的问题是:如果在返回 jint 的 JNI 方法中抛出异常,我应该返回什么?
Suppose I have a Java class like this:
public class Test
{
static { System.loadLibrary("test"); }
public native int foo();
}
Suppose that the foo() method is doing some JNI calls, and one of these calls fails (IE, throws an exception). I would then like to return from the JNI code and have the exception thrown in Java. For example:
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;
}
The problem is that return NULL
is not a jint. In Android for example, I would get this warning when compiling:
warning: return makes integer from pointer without a cast.
Now the question is: What should I return in case of an Exception being thrown inside a JNI method that returns a jint?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您的代码(或库)在 Java 中引发
Exception
,那么无论您返回什么值,Java 都会忽略它。显然它需要是兼容的类型 - 因此在您的示例中返回0
似乎是有意义的,或者您喜欢的任何类型。当您的代码返回时,Java 运行时将注意到已引发Exception
并继续传播它并忽略函数的返回值。当然,您需要返回兼容的类型。不要简单地返回
NULL
,因为当函数未声明为返回指针时,它将被转换为int
,这可能不合适。但显然,当您调用 C 函数时,它们不会引发
Exception
。因此,您可以将整数映射到错误条件(例如-1
),然后在 Java 中抛出Exception
,或者您可以花时间构建一个>JNI 中的异常
。If your code (or a library) raises an
Exception
in Java, it doesn't matter what value you return, Java will ignore it. Obviously it needs to be a compatible type - so returning0
in your example would seem to make sense, or whatever you're comfortable with. When your code returns, the Java runtime will notice that anException
has been raised and continue to propagate it and ignore the return value of your function.You will, of course, need to return a compatible type. Don't simply return
NULL
, as that will be cast to anint
when the function is not declared to return a pointer, which may not be appropriate.Obviously, though, when you're calling C functions, those would not raise an
Exception
. So you can either map an integer to an error condition (-1
for example) and then throw theException
in Java, or you can take the time to build anException
in JNI.编辑:另请参阅这个优雅的答案,使用函数而不是底部预处理器宏。
我提供了一个示例来完成爱德华·汤姆森的回答。
在此示例中,JNI 非 void 函数
return 0;
C 预处理器宏
CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION
出现在所有上述 JNI 函数的末尾。EDIT: See also this elegant answer using a function instead of the bottom preprocessor macro.
I provide an example to complete the Edward Thomson's answer.
In this example the JNI non-void functions
return 0;
The C preprocessor macro
CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION
is present at the end of all the above JNI functions.