c语言捕获异常,在Native代码中捕获与抛出异常

以下的代码中展示了如何声明一个抛出异常的Native函数。`CatchThrow`类声明了`doit`这个Native函数,并且指定了它将有可能抛出一个`IllegalArgumentException`.

~~~

public class CatchThrow {

static {

System.loadLibrary("CatchThrow");

}

private native void doit() throws IllegalArgumentException;

private void callback() throws NullPointerException {

throw new NullPointerException("CatchThrow.callback");

}

public static void main(String[] args){

CatchThrow c = new CatchThrow();

try {

c.doit();

}catch (Exception e){

System.out.println("In Java:\n\t" + e);

}

}

}

~~~

CatchThrow.main函数调用的Native方法doit的JNI实现如下:

~~~

/*

* Class: CatchThrow

* Method: doit

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_CatchThrow_doit

(JNIEnv * env, jobject obj){

jthrowable exc;

jclass cls = (*env)->GetObjectClass(env, obj);

jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V");

if(!mid){

return;

}

(*env)->CallVoidMethod(env, obj, mid);

exc = (*env)->ExceptionOccurred(env);

if(exc){

/*

* We don't do much with the exception, except that we print a debug message for it,

* clear it, and throw a new exception.

*/

jclass newExcCls;

(*env)->ExceptionDescribe(env);

(*env)->ExceptionClear(env);

newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");

if(!newExcCls){

/*Unable to find the exception class, give up. */

return;

}

(*env)->ThrowNew(env, newExcCls, "thrown from C code");

}

}

~~~

执行最终的可执行程序将会产生如下输出:

~~~

Exception in thread "main" java.lang.NullPointerException: CatchThrow.callback

at CatchThrow.callback(CatchThrow.java:7)

at CatchThrow.doit(Native Method)

at CatchThrow.main(CatchThrow.java:12)

In Java:

java.lang.IllegalArgumentException: thrown from C code

~~~

回调函数跑出了一个NullPointerException.当CallVoidMethod返回到Native函数时,Native代码通过ExceptionOccurred函数检测到这个异常。在我们的示例中,当异常被检测到的时候, Native代码通过调用ExceptionDescribe输出了一段描述性信息,然后调用ExceptionClear清除了异常信息,最后抛出了一个IllegalArgumentException.

JNI代码引起的异常(例如,通过ThrowNew抛出的异常)不会立即打断Native代码的执行流程。这与Java程序语言中异常处理逻辑是不同的。在Java语言中,如果有异常被抛出,虚拟机就会自动的把控制流程转向匹配异常类型的最近层次的try/catch语句声明,然后虚拟机清空异常并继续执行异常处理逻辑。相比之下,JNI程序员在异常出现的时候必须显示实现代码的控制流程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值