1

以下は、文字列を作成して呼び出し元の Java メソッドに返す jni メソッドのサンプルです。

jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    char test[100];
    sprintf(test, "Test%03d.txt", rand()/100);
    jstring returnVal = (*env)->NewStringUTF(env, test);
    (*env)->DeleteLocalRef(env,returnVal);
    return returnVal;
}

ローカル参照を削除したため、呼び出し元の Java メソッドで jstring が無効になると予想していました。しかし、参照はまだ有効です。System.gc() を明示的に呼び出して、GC がクリアするかどうかを確認しましたが、発生しませんでした。

これによると:http://android-developers.blogspot.com/2011/11/jni-local-reference-changes-in-ics.html

"Bug: Calling DeleteLocalRef() and continuing to use the deleted reference
It shouldn’t need to be said that it’s illegal to continue to use a reference after calling DeleteLocalRef() on it, but because it used to work, so you may have made this mistake and not realized. The usual pattern seems to be where native code has a long-running loop, and developers try to clean up every single local reference as they go to avoid hitting the local reference limit, but they accidentally also delete the reference they want to use as a return value!

The fix is trivial: don’t call DeleteLocalRef() on a reference you’re going to use (where “use” includes “return”)."

私は矛盾について少し混乱しています。

4

1 に答える 1

2

どの SDK レベルをターゲットにしていますか? 13 以下 (ICS 以前) を対象とする場合、古い JNI の動作が得られ、このコードは機能するはずです (ただし、技術的にはまだ正しくありません)。

14 (ICS) 以上をターゲットにしている場合、表示されているコードはプレゼント エラーで失敗します。

memory map fault addr deadd00d

SDK 14+ を対象としている場合でもコードは機能しますが、以前のバージョンの Android でアプリを実行することに注意してください。

于 2013-06-06T16:39:41.380 に答える