JNI--异常处理

JAVA中可以使用try catch捕获异常,那么JNI中如果发生了异常会是什么现象呢?
我们在JAVA中定义native方法,并调用
package com.aruba.jniapplication;

/**
 * JNI 引用
 */
public class JniDemo6 {

    static {
        System.load("C:\\Users\\tyqhc\\source\\repos\\JniApplication\\x64\\Debug\\JniApplication.dll");
    }

    public native void getException();

    public static void main(String[] args) {
        JniDemo6 jniDemo6 = new JniDemo6();
        try {
            jniDemo6.getException();
        } catch (Exception e) {
            
        }
    }

}
编写C++代码,故意报一个异常
//获取异常
JNIEXPORT void JNICALL Java_com_aruba_jniapplication_JniDemo5_getException
(JNIEnv* env, jobject jobj) {
    jclass jclz = env->GetObjectClass(jobj);
    jfieldID fid = env->GetFieldID(jclz,"key","Ljava/lang/String;");

    jstring jstr = (jstring)env->GetObjectField(jobj,fid);

    printf("c++ have exception \n");
}
很明显JniDemo6 中并没有key这个成员变量,编译后运行,看java是否能够捕获异常:
结果是:Java的try catch并捕获不到native方法的异常,还是报错了!但是C++代码还能往下执行,打印输出了信息!
JNI中异常处理有用自己的一套规则,需要JNI开发者在有可能产生异常的位置,调用env的ExceptionCheck方法,检查一下是否有异常
//获取异常
JNIEXPORT void JNICALL Java_com_aruba_jniapplication_JniDemo6_getException
(JNIEnv* env, jobject jobj) {
    jclass jclz = env->GetObjectClass(jobj);
    jfieldID fid = env->GetFieldID(jclz,"key","Ljava/lang/String;");

    jstring jstr = (jstring)env->GetObjectField(jobj,fid);

    //检查是否有异常
    jboolean has_exception =  env->ExceptionCheck();
    if (has_exception) {
        //清空异常
        env->ExceptionClear();
    }

    printf("c++ have exception \n");
}
在执行Java代码
public static void main(String[] args) {
        JniDemo6 jniDemo6 = new JniDemo6();
        try {
            jniDemo6.getException();
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
Java层已经不会报错了,但是也没有捕获异常,因为在native层已经将这个异常清掉了,我们需要手动创建一个异常告诉Java层,修改c++代码:
//获取异常
JNIEXPORT void JNICALL Java_com_aruba_jniapplication_JniDemo6_getException
(JNIEnv* env, jobject jobj) {
    jclass jclz = env->GetObjectClass(jobj);
    jfieldID fid = env->GetFieldID(jclz,"key","Ljava/lang/String;");

    jstring jstr = (jstring)env->GetObjectField(jobj,fid);

    //检查是否有异常
    jboolean has_exception =  env->ExceptionCheck();
    if (has_exception) {
        //清空异常
        env->ExceptionClear();
        jclass newExc = env->FindClass("java/lang/Exception");
        if(newExc != NULL)  env->ThrowNew(newExc,"c++ have exception to Java");
    }

    printf("c++ have exception \n");
}
在执行Java代码:
JNI的异常处理就到此结束了,总之有点坑爹,需要我们自己创建Java层的异常,Java才能捕获异常
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值