1

JNIのローカルおよびグローバル参照に関するいくつかの参照を読みました。しかし、JNI関数にパラメーターとして渡されるJavaオブジェクトがローカル参照であるか、グローバル参照であるかについて、明確な答えを見つけることができませんでした。私はそれがグローバルであるべきだと思っていましたが、1つの問題があります:

まず、Javaオブジェクトポインタを取得して保存します。次に、ネイティブコールバック関数がそのオブジェクトのメソッドを呼び出します。コールバック関数は別のスレッドから呼び出されます。スレッドはAttachCurrentThread()を使用して作成されたため、JVMはそれを認識しています。JNIEnv *変数も有効であり、オブジェクトはガベージコールされていませんでしたが、警告が表示されてからクラッシュします。

JNI警告:0x4108edb8は、Lcom / my / company / MyClass; .load:(Ljava / lang / String;)V(GetObjectClass)の有効なJNI参照ではありません

4

2 に答える 2

5
  1. これはローカルリファレンスです。「オブジェクトはローカル参照としてネイティブメソッドに渡されます」

  2. JNIEnv *ポインターは、スレッド境界はもちろん、JNIメソッド呼び出し境界を越えて無効です。

  3. あなたの状況では、コールバックメソッドで使用するためにローカル参照をグローバル参照に変換する必要があります。

于 2012-04-24T04:06:57.897 に答える
0

理論的には、関数がJavaコードから呼び出されない場合はグローバル参照を取得できます(JVMに要求せずに他のJNIメソッドから直接JNIメソッドを呼び出すこともあります)が、常にローカルであると想定し、そのように扱う必要があります。後で使用するためにそれらを保存する場合は、新しいgobal参照を作成する必要があります。実際、グローバル参照を取得できたとしても、それらの処理方法に違いはありません。いずれの場合も削除する必要はありません。グローバル参照を取得したとしても(上記の方法が唯一の方法だと思います)、最初に新しい参照を作成せずに保存するのは間違いです。あなたにそれを与えた人がrefを削除すると、それは無効になります。

編集:上記は編集されたバージョンであり、@EJPをさらに満足させることを願っています。同じメッセージですが、より明確です。そして彼は、ほとんどすべての場合、この場合は違いがないとしても、JNI仕様が重要であるという点を持っています:-)

于 2012-04-23T21:12:23.993 に答える