2012-06-15 3 views
7

좋아요, 아래 네이티브 코드가 있습니다. FilePermissionInfo의 배열을 반환하려고합니다. stat()가 반환 한 일부 데이터가 채워집니다.NewObject 호출에 대한 간접 참조가 잘못되었습니다.

06-14 20 : 25 : 17.621 : dalvikvm/W (2287) : 문제 NewObject에 처음이라고 할 때 다음과 같은 에러가 발생한다는 것이다 잘못된 간접 참조 0x40005820 decodeIndirectRef 06-14에 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; 

}

자바 클래스 생성자 서명 및 경로는 다음과 같습니다

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"와 작동합니다. 궁극적으로 그 클래스의 setter를 사용하여 값을 설정할 수 있지만 호출하는 것을 좋아하지 않습니다. JNI 경계를 넘는 너무 많은 메소드 –

답변

13

좋아, 찾았습니다. 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이 비어있는 경우에도 여전히 문제가있는 것인지 확신 할 수 없습니다. (예 : env) -> NewStringUTF (env, NULL) 이 문제가 발생했지만 다음과 같은 것을 사용하여 문제를 해결할 수있었습니다 : std : string empty (""); jstring myemptyString = (* env) -> NewStringUTF (empty.c_str()); 4.3. –

관련 문제