JNIを使用しているときに興味深い問題が発生しました。一例を与えるために、私は次のようなクラスがある:JNI Register static with static initializer
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;
}
FindClass
が対象クラスの静的イニシャライザブロックを実行するため、上記のコードはJNIEnv.FindClass
が呼び出された後に失敗します。この場合、ターゲットクラスはRegisterNatives
呼び出し後にのみリンクされるネイティブメソッドを呼び出します。これはUnsatisfiedLinkError
になります。
JNIEnv.FindClass
を呼び出す方法は、そのクラスのネイティブメソッドをリンクするために、対象クラスの静的イニシャライザブロックを実行しないでください。理想的には、可能ならばJavaコードを変更しないでください。
共有ライブラリ 'System.loadLibrary()'と、 'RegisterNatives()'の代わりに 'javah'によって生成されたネイティブメソッドの従来の命名法を使用します。 – EJP
RegisterNativesでこれを行う方法はありますか、この場合は不可能ですか? – konsolas