2017-02-26 11 views
1

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コードを変更しないでください。

+0

共有ライブラリ 'System.loadLibrary()'と、 'RegisterNatives()'の代わりに 'javah'によって生成されたネイティブメソッドの従来の命名法を使用します。 – EJP

+0

RegisterNativesでこれを行う方法はありますか、この場合は不可能ですか? – konsolas

答えて

0

セクションでネイティブコールを使用するクラスでRegisterNativesを使用することは不可能です。