12. 异常错误处理:
在Java编程语言中,可以通过异常中断当前正在执行的操作,并退出当前操作所在的函数。然而当我们使用native方法的时候,由于是C语言并不支持异常,这样便需要JNI提供一组操作Java异常的方法,以便在二者之间可以共享异常信息。需要注意的是,即便C++中支持异常,也无法将C++中的异常和Java中的直接关联在一起,更无法在两者之间相互转换。这里我们还是通过代码示例的方式,并结合关键的注释来了解这些JNI函数的用法和机制。
1) 包含native方法的Java类代码:
1 import java.io.PrintWriter;
2 public class Printf {
3 public static native void fprint(PrintWriter ps,String format,double x);
4 static {
5 System.loadLibrary(\"Printf\");
6 }
7 }
2) 实现本地方法的C语言代码:
1 #include \"Printf.h\"
2 #include <stdlib.h>
3 #include <string.h>
4 #include <float.h>
5 JNIEXPORT void JNICALL Java_Printf_fprint
6 (JNIEnv* env, jclass cl, jobject out, jstring format, jdouble x)
7 {
8 //这里是通过ThrowNew方法生成一个异常对象,这里FindClass查找的是
9 //运行时异常NullPointerException,需要注意的是,对于C语言的代码,
10 //在调用ThrowNew之后,并不会在C代码内部抛出异常,因此在调用ThrowNew后,
11 //其后面的代码仍然可以继续执行。然而由于异常标识一种错误的状态,因此
12 //在通常情况下,我们都会在ThrowNew的后面释放一些资源,之后立刻调用
13 //return退出当前的native方法。
14 //在native方法退出后,其调用的ThrowNew将会发挥作用,JVM会将抛出的
15 //异常返给native方法的最近调用者(Java代码)。
16 if (format == NULL) {
17 env->ThrowNew(env