0

ネイティブ コードから JNI コールバックを作成すると、致命的なエラーが発生します。

SIGSEGV ..

Distribution: CentOS release 5.9 (Final), x64

Problematic frame:

V  [libjvm.so+0x53499f]  JNI_CreateJavaVM+0x20e6f

そして、問題にとって重要なコード:

JavaVM *JVM;
JavaVMAttachArgs args;

jobject jlistener;
jmethodID callback;


JNIEXPORT void JNICALL JNI_FUNC_NAME(open) (JNIEnv *env, jobject obj, jobject config) {
    env->GetJavaVM(&JVM);

    args.version = JNI_VERSION_1_6; 
    args.name = "notifyThread"; 
    args.group = NULL; 

    // ...
}

JNIEXPORT void JNICALL JNI_FUNC_NAME(setListener) (JNIEnv *env, jobject obj, jobject listener) {
    jlistener = env->NewGlobalRef(listener);
    jclass thisClass = env->GetObjectClass(listener);

    jmethodID callback = env->GetMethodID(thisClass, "messageRx", "(B)V");
    // if (NULL == notifyMethod) return;

    return;
}


void notify(jbyte x) {
    JNIEnv *jniEnv;
    int envState = JVM->GetEnv((void **)&jniEnv, 0x00010006);

    if(envState == (-2)) {
        if(JVM->AttachCurrentThread((void**)&jniEnv, &args) != 0)
            jniEnv->ThrowNew(exc, "Could not attach current notifying thread.");
    }

    jniEnv->CallVoidMethod(jlistener, callback, x); // notify

    JVM->DetachCurrentThread();
}

コールバック行 ( ) をコメントアウトするjniEnv->CallVoidMethod ...と、問題はなく、すべてが期待どおりに機能します。問題は実際のコールバックにあり、奇妙なことに、一部の JVM では機能します。

これについて何か考えはありますか?

4

1 に答える 1

0

問題は、リスナー オブジェクトへのグローバル参照を作成する前にコールバックが使用されることでした (jlistener初期化されませんでした)。

于 2013-09-06T10:51:31.623 に答える