好的,所以我有下面的本机代码.
@H_404_2@我试图从它返回一个FilePermissionInfo数组,填充stat()返回的一些数据.
@H_404_2@问题是第一次调用NewObject时出现以下错误:
06-15 20:25:17.621: W/dalvikvm(2287): Invalid indirect reference@H_404_2@ 0x40005820 in decodeIndirectRef 06-15 20:25:17.621: E/dalvikvm(2287):@H_404_2@ VM aborting
这很奇怪,因为我唯一的参考对象是jclass(对于FilePermissionInfo),我把它变成了一个全局引用.
代码是:
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,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,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,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";
解决方法
好的,找到了.
@H_404_2@这是jstring参数的问题.事实证明,你不能将空字符串(或者甚至是NULL)作为jstring传递.
@H_404_2@相反,我使用(* env) – > NewStringUTF(env,NULL)来创建NULL jstring.
好像现在好了.
由于这个问题产生了一定程度的高活动,我将在下面发布最终解决方案.请注意,nullString变量在其作用域的末尾(或者当您使用它时)被释放:
jstring nullString = (*env)->NewStringUTF(env,NULL); ... jobject permInfo = (*env)->NewObject(env,(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,(jboolean)1,nullString); ... (*env)->DeleteLocalRef(env,nullString);