使用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代码。
答案 0 :(得分:0)
将RegisterNatives用于在节中使用本机调用的类是不可能的。