5

生成されたスレッドが C++ から静的 Java メソッドを呼び出すようにするためのコードを書いています。

メソッドを呼び出すビットは、Java からのネイティブ呼び出しに配置されている場合は正常に機能しますが、JNIEnv が添付されたスレッドからではありません。

JavaVM* を次のように設定しました。

jint JNI_OnLoad(JavaVM* jvm, void* reserved)
{
    LOGI("Setting Java Virtual Machine");

    ThreadJNIEnvironment::javaVM = jvm;

    return JNI_VERSION_1_6;
}

これは呼び出されます。

次に、別のスレッドを生成し、このスレッドから次のことを行います。

JNIEnv* env;
jint ret = ThreadJNIEnvironment::javaVM->AttachCurrentThread(&env, NULL);

LOGI("AttachCurrentThread returned %d", ret);

jclass interfaceClass = env->FindClass("com/ecmsys/mcb/model/McbInterface");
jmethodID testMethod = env->GetStaticMethodID(interfaceClass, "Test", "()V");
env->CallStaticVoidMethod(interfaceClass, testMethod);

AttachCurrentThread は 0 を返します。

GetStaticMethod は次のエラーで失敗します:

Fatal signal 11 (SIGSEGV) at 0x0000002c (code=1).....

私はそれを混乱させるために何をしたのかわかりません...ああ待ってください...いくつかのセットアップを行わずに生成されたスレッドからJavaアプリケーションクラスにアクセスすることはできません...

jint JNI_OnLoad(JavaVM* jvm, void* reserved)
{
    LOGI("Setting Java Virtual Machine");
    ThreadJNIEnvironment::javaVM = jvm;

    JNIEnv* env;


    jvm->AttachCurrentThread(&env, NULL);
    jclass mcbInterface = env->FindClass("com/ecmsys/mcb/model/McbInterface");
    ThreadJNIEnvironment::interfaceClass = env->NewGlobalRef(mcbInterface);

    return JNI_VERSION_1_6;
} 

次に、これを行います:

JNIEnv* env;
jint ret = ThreadJNIEnvironment::javaVM->AttachCurrentThread(&env, NULL);

LOGI("AttachCurrentThread retured %d", ret);

if(ThreadJNIEnvironment::interfaceClass)
{
    jmethodID testMethod = env-->GetStaticMethodID(static_cast<jclass>ThreadJNIEnvironment::interfaceClass), "Test", "()V");
    env->CallStaticVoidMethod(static_cast<jclass>(ThreadJNIEnvironment::interfaceClass), testMethod);
}


ThreadJNIEnvironment::javaVM->DetachCurrentThread();

あなたは生きて学びます!

4

1 に答える 1

4

検索後に例外をチェックするかinterfaceClass( env->ExceptionCheck())、単に非 NULL であることをチェックします。ほとんどの場合、クラス ルックアップが失敗しています。

于 2013-01-25T14:25:22.433 に答える