2012-06-15 20 views
7

OK、以下のネイティブコードがあります。 私はFilePermissionInfoの配列を返そうとしていますが、stat()によって返されたいくつかのデータが格納されています。NewObject呼び出しで間接参照が無効です

06から15:20:25:17.621:dalvikvm/W(2287): 問題は、のNewObjectが最初に呼び出されたときに、私は次のエラーを取得することで無効な間接参照 0x40005820 decodeIndirectRef 6月15日に20:25:17.621:E/dalvikvm(2287):私が持っている唯一の参照オブジェクトが(FilePermissionInfo用)JCLASSあるので VMは、

それは奇妙だ

を中止し、私はグローバル参照にそれを回します。

コードは次のとおりです。

JNIEXPORT jobjectArray JNICALL 
Java_com_mn_rootscape_utils_NativeMethods_getFilesPermissions(JNIEnv* env, jobject thizz, jobjectArray filePathsArray) 
{ 
jobjectArray result; 
int size = (*env)->GetArrayLength(env, filePathsArray); 
jboolean isCopy; 

jclass filePermInfoCls = (*env)->FindClass(env, kFilePermissionInfoPath); 
if(!filePermInfoCls) 
{ 
    LOGE("getFilesPermissions: failed to get class reference."); 
    return NULL; 
} 

gFilePermInfoClass = (jclass)(*env)->NewGlobalRef(env, filePermInfoCls); 
LOGI("got gFilePermInfoClass"); 

jmethodID filePermInfoClsConstructor = (*env)->GetMethodID(env, gFilePermInfoClass, "<init>", kFilePermInfoConstructorSig); 
if(!filePermInfoClsConstructor) 
{ 
    LOGE("getFilesPermissions: failed to get method reference."); 
    return NULL; 
} 

struct stat sb; 

LOGI("starting..."); 
result = (jobjectArray)(*env)->NewObjectArray(env, size, gFilePermInfoClass, NULL); 
for(int i = 0; i != size; ++i) 
{ 
    jstring string = (jstring) (*env)->GetObjectArrayElement(env, filePathsArray, i); 
const char *rawString = (*env)->GetStringUTFChars(env, string, &isCopy);  

    if(stat(rawString, &sb) == -1) 
    { 
     LOGE("stat error for: %s", rawString); 
    } 

    LOGI("%ld %ld %ld %ld %ld %ld %ld %ld", sb.st_dev, sb.st_mode, sb.st_nlink, sb.st_uid, sb.st_gid, sb.st_atime, sb.st_mtime, sb.st_ctime); 

    jobject permInfo = (*env)->NewObject(env, 
          gFilePermInfoClass, 
          filePermInfoClsConstructor, 
          (long)sb.st_dev, 
          (long)sb.st_mode, 
          (long)sb.st_nlink, 
          (long)sb.st_uid, 
          (long)sb.st_gid, 
          (long)sb.st_atime, 
          (long)sb.st_mtime, 
          (long)sb.st_ctime, 
          "", 
          "", 
          1, 
          ""); 

    LOGI("xxx1"); 
    (*env)->SetObjectArrayElement(env, result, i, permInfo); 
    LOGI("xxx2"); 
    (*env)->ReleaseStringUTFChars(env, string, rawString); 
    LOGI("xxx3"); 
} 

(*env)->DeleteLocalRef(env, filePermInfoCls); 

return result; 

}

のJavaクラスのコンストラクタの署名とパスは次のとおりです。

const char* kFilePermissionInfoPath = "com/mn/rootscape/utils/FilePermissionInfo"; 
const char* kFilePermInfoConstructorSig = "(JJJJJJJJLjava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V"; 

私はデフォルトコンストラクタでのNewObjectを呼び出す場合、それが動作することに注意してください良い。

+0

私は本当にこれはNDK(V8)のバグではありません願っています。私はあらゆる種類のアプローチを試みましたが、それはデフォルトのコンストラクタ(つまり "()V"で動作するのは非常に奇妙です。 最終的には、そのクラスのセッターを使用して値を設定できますが、 –

答えて

13

OK、見つかりました。 jstringパラメータに問題がありました。空の文字列(またはその場合はNULL)をjstringとして渡すことはできません。 代わりに(*env)->NewStringUTF(env, NULL)を使用してNULL jstringを作成しました。

今すぐ動作するようです。


この質問には多少の高いアクティビティが生じているので、私は以下の最終的な解決策を投稿しています。 nullString変数は(あなたがそれを使用して行われている場合、または)その範囲の最後に割り当てが解除されていることに注意してください:

 jstring nullString = (*env)->NewStringUTF(env, NULL); 
... 
     jobject permInfo = (*env)->NewObject(env, 
           gFilePermInfoClass, 
           filePermInfoClsConstructor, 
           (jbyte)permsOwner, 
           (jbyte)permsGroup, 
           (jbyte)permsOthers, 
           (jlong)sb.st_uid, 
           (jlong)sb.st_gid, 
           (jlong)sb.st_atime, 
           (jlong)sb.st_mtime, 
           (jlong)sb.st_ctime, 
           nullString, 
           nullString, 
           (jboolean)1, 
           nullString); 
... 
     (*env)->DeleteLocalRef(env, nullString); 
+2

'(* env) - > NewObject(...)'関数呼び出しの '' "、" "、'引数を 'jstring myNullString =(*)'に置き換えたことを意味しますか? –

+1

@ m-ric:はい、それは正しいです。 –

+0

私はこれが空のjstringsにもともと述べたようにまだ問題であるとは確信していません。この問題に対処していましたが、次のようなものを使って修正できました:std:string empty( ""); jstring myemptyString =(* env) - > NewStringUTF(empty.c_str()); 4.3。 –

関連する問題