Referencia indirecta no válida en la llamada NewObject

Aceptar, así que tengo el código nativo a continuación. Estoy tratando de devolver una matriz de FilePermissionInfo de ella, rellenado con algunos datos devueltos por stat (). El problema es que consigo el error siguiente cuando NewObject se llama la primera vez:

06-15 20: 25: 17.621: W / dalvikvm (2287): Referencia indirecta no válida 0x40005820 en decodeIndirectRef 06-15 20: 25: 17.621: E / dalvikvm (2287): VM aborting

Es extraño, porque el único objeto de referencia que tengo es el jclass (para FilePermissionInfo) y lo convierto en una referencia global.

El código es:

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; 

}

La firma y la ruta del constructor de la clase Java son:

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

Tenga en cuenta que si llamo a NewObject en el constructor predeterminado, entonces funciona bien.

OK, lo encontré. Fue un problema con los parámetros jstring . Resulta que no puedes pasar cadenas vacías (ni siquiera NULL para esa materia) como jstring . En su lugar usé (*env)->NewStringUTF(env, NULL) para crear un jstring NULL.

Parece que funciona bien ahora.


Dado que esta pregunta generó algo de una actividad alta, estoy publicando la solución final a continuación. Tenga en cuenta que la variable nullString se desasigna al final de su ámbito (o cuando haya terminado de usarlo):

  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); 
  • Gifflen Señal Fatal 11
  • Violación de acceso en código nativo con acelerador acelerado del decodificador de MediaCodec de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.