JNI异常处理

来源:互联网 发布:pc端淘宝首页不见了 编辑:程序博客网 时间:2024/06/05 09:34


在java中,我们经常需要处理异常。然而,在C本地方法中,我们同样需要处理异常。

下面我们来看下一般的处理:

class 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);        }    }    static {        System.loadLibrary("CatchThrow");    }}

 

当本地方法调用Callback方法抛出一个异常后,(*env)->ExceptionOccurred(env);方法将返回true。然后本地方法在抛出一个本地异常,通过(*env)->ThrowNew()抛出异常。所以,本地方法最终也是调用java方法来抛出异常的。

打印结果:
java.lang.NullPointerException:        at CatchThrow.callback(CatchThrow.java)        at CatchThrow.doit(Native Method)        at CatchThrow.main(CatchThrow.java)In Java:        java.lang.IllegalArgumentException: thrown from C code

既然这样,我们可以专门提供一个工具方法,用于抛出异常。

关于函数名称:JNU表示JNIUtilities(JNI工具)。


下面提供一个更全面的异常工具方法:

jvalueJNU_CallMethodByName(JNIEnv *env,                     jboolean *hasException,                     jobject obj,                     const char *name,                     const char *descriptor, ...){    va_list args;    jclass clazz;    jmethodID mid;    jni.book Page 79 Thursday, February 21, 2002 4:36 PM    6.2.3 Exceptions in Utility Functions EXCEPTIONS    80    jvalue result;    if ((*env)->EnsureLocalCapacity(env, 2) == JNI_OK) {        clazz = (*env)->GetObjectClass(env, obj);        mid = (*env)->GetMethodID(env, clazz, name,                                  descriptor);        if (mid) {            const char *p = descriptor;            /* skip over argument types to find out the            return type */            while (*p != ')') p++;            /* skip ')' */            p++;            va_start(args, descriptor);            switch (*p) {                case 'V':                    (*env)->CallVoidMethodV(env, obj, mid, args);                    break;                case '[':                case 'L':                    result.l = (*env)->CallObjectMethodV(                            env, obj, mid, args);                    break;                case 'Z':                    result.z = (*env)->CallBooleanMethodV(                            env, obj, mid, args);                    break;                case 'B':                    result.b = (*env)->CallByteMethodV(                            env, obj, mid, args);                    break;                case 'C':                    result.c = (*env)->CallCharMethodV(                            env, obj, mid, args);                    break;                case 'S':                    result.s = (*env)->CallShortMethodV(                            env, obj, mid, args);                    break;                case 'I':                    result.i = (*env)->CallIntMethodV(                            env, obj, mid, args);                    break;                case 'J':                    result.j = (*env)->CallLongMethodV(                            env, obj, mid, args);                    break;                case 'F':                    result.f = (*env)->CallFloatMethodV(                            jni.book Page 80 Thursday, February 21, 2002 4:36 PM                    EXCEPTIONS Exceptions in Utility Functions 6.2.3                    81                    env, obj, mid, args);                    break;                case 'D':                    result.d = (*env)->CallDoubleMethodV(                            env, obj, mid, args);                    break;                default:                    (*env)->FatalError(env, "illegal descriptor");            }            va_end(args);        }        (*env)->DeleteLocalRef(env, clazz);    }    if (hasException) {        *hasException = (*env)->ExceptionCheck(env);    }    return result;}

调用方法:

JNIEXPORT void JNICALLJava_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj){    printf("In C\n");    JNU_CallMethodByName(env, NULL, obj, "callback", "()V");}


0 0