6

Android NDKを使い始めたばかりですが、Cコードで次の呼び出しを行うとSIGSEGVを取得し続けます。

jobjectArray someStringArray;
someStringArray = (*env)->NewObjectArray(env, 10, 
(*env)->FindClass(env,"java/lang/String"),(*env)->NewStringUTF(env, ""));

私が見つけることができるすべての例に基づいて、上記のコードは正しいですが、私はSIGSERGVを取得し続け、NewObjectArray行がコメント化されていればすべて問題ありません。何がそのような問題を引き起こす可能性があるのか​​考えていますか?

4

2 に答える 2

5

それは正しいように見えるので、私はあなたが何か他の間違ったことをしたと思います。checkjniをオンにして実行していると思いますか?これを複数の行に分割することをお勧めします。FindClassを実行して戻り値を確認し、NewStringUTFを実行して戻り値を確認してから、NewObjectArrayを呼び出します。

ところで、最後の引数としてNULLを渡したい場合があります。配列の各要素のデフォルト値として空の文字列を使用するこのパターンは一般的に使用されます(Sunのドキュメントからコピー&ペーストされ、そこから広がっていると思います)が、ほとんど役に立たず、少し無駄です。(そして、Javaの「newString [10]」の動作とは一致しません。)

于 2010-01-23T21:34:28.480 に答える
2

考えられる原因の1つは、長期実行のJNIメソッドで、メソッド呼び出しごとのローカル参照スロット(通常、Androidでは512スロット)が不足するとVMが異常終了することです。

FindClass()関数とNewStringUTF()関数はローカル参照を割り当てるため、JNIメソッドに長時間留まると、VMは特定のローカル参照をリサイクルする必要があるかどうかを認識しません。したがって、不要になったときに取得したローカル参照を解放するには、明示的にDeleteLocalRef()を呼び出す必要があります。これを行わないと、「ゾンビ」ローカル参照がVMのスロットを占有し、すべてのローカル参照スロットが不足しているときにVMが異常終了します。

短期間のJNIメソッドでは、JNIメソッドを終了するときにすべてのローカル参照が再利用されるため、これは問題にならない場合があります。

于 2011-08-12T19:32:00.657 に答える