JNI RegisterNatives在静态初始化程序中使用本机调用

时间:2017-02-26 23:07:00

标签: java c java-native-interface

使用JNI时遇到了一个有趣的问题。举个例子,我有一个如下的类:

public class AClass {
    private static int someInteger;

    public static native int getInteger();

    static {
        someInteger = getInteger();
    }
}

上面这个类的问题是,如果我有一个试图用JNI_OnLoad注册本机的JNI库,如下所示:

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env; (*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6);

    JNINativeMethod table[] = {
            {"getInteger", "()I", (void *) &native_getInteger)},
        };

    jclass cls = (*env)->FindClass(env, "AClass");

    if ((*env)->ExceptionCheck(env)) {
        (*env)->ExceptionDescribe(env);
        return JNI_ERR;
    }

    printf("RegisterNatives return value: %d", (*env)->RegisterNatives(env, cls, table, 1));
    return JNI_VERSION_1_6;
}

上面的代码在调用JNIEnv.FindClass后失败,因为FindClass运行目标类的静态初始化程序块。在这种情况下,目标类调用仅在RegisterNatives调用后链接的本机方法。这会产生UnsatisfiedLinkError

有没有办法在不运行目标类的静态初始化程序块的情况下调用JNIEnv.FindClass以链接该类的本机方法?理想情况下,如果可能的话,我想避免更改java代码。

1 个答案:

答案 0 :(得分:0)

将RegisterNatives用于在节中使用本机调用的类是不可能的。