2010年10月14日 星期四

JNI - Local and Global References

  • Local References
  • A local reference is valid only within the dynamic context of the native method that creates it, and only within that one invocation of the native method.
    P.S. You must not write native methods that store a local reference in a static variable and expect to use the same reference in subsequent invocations.
    (Example) MyNewString(): It is a modified version of the MyNewString function in before, uses local references incorrectly.
    /* This code is illegal */
    jstring
    MyNewString(JNIEnv *env, jchar *chars, jint len)
    {
        static jclass stringClass = NULL;
        jmethodID cid;
        jcharArray elemArr;
        jstring result;
    
        if (stringClass == NULL) {
            stringClass = (*env)->FindClass(env, "java/lang/String");
            if (stringClass == NULL) {
                return NULL; /* exception thrown */
            }
        }
        /* It is wrong to use the cached stringClass here, because it may be invalid. */
        cid = (*env)->GetMethodID(env, stringClass, "<init>", "([C)V");
        ...
        elemArr = (*env)->NewCharArray(env, len);
        ...
        result = (*env)->NewObject(env, stringClass, cid, elemArr);
        (*env)->DeleteLocalRef(env, elemArr);
        return result;
    }
    
    The goal for caching stringClass in a static variable might have been to eliminate the overhead of repeatedly making the following function call:
    FindClass(env, "java/lang/String");
    
    This is not the right approach because FindClass returns a local reference to the java.lang.String class object. To see why this is a problem, suppose that the native method implementation of C.f calls MyNewString:
    JNIEXPORT jstring JNICALL
    Java_C_f(JNIEnv *env, jobject this)
    {
        char *c_str = ...;
        ...
        return MyNewString(c_str);
    }
    
  • Global References

0 意見: