问题描述
好了,我有天然code以下。我试图返回FilePermissionInfo从一个数组,填充()由stat返回的一些数据。问题是,我得到以下错误,当被NewObject的第一次调用:
OK, so I have the native code below.I'm trying to return an array of FilePermissionInfo from it, populated with some data returned by stat().The problem is that I get the following error when NewObject is called the first time:
06-15 20:25:17.621:W / dalvikvm(2287):无效的间接引用 0x40005820在德codeIndirectRef 06-15 20:25:17.621:E / dalvikvm(2287): VM终止执行
这是奇怪的,因为只有参考对象我是JCLASS(对于FilePermissionInfo),我把它转化为一个全球性的参考。
It's odd, because the only reference object I have is the jclass (for FilePermissionInfo) and I turn it to a global reference.
在code是:
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类的构造函数签名和路径是:
The Java class constructor signature and path are:
const char* kFilePermissionInfoPath = "com/mn/rootscape/utils/FilePermissionInfo";
const char* kFilePermInfoConstructorSig = "(JJJJJJJJLjava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V";
请注意,如果我叫上NewObject的默认构造函数那么它工作正常。
Please note that if I call NewObject on the default constructor then it works fine.
推荐答案
好了,找到了。正是有了的jstring
参数有问题。事实证明,你不能将空字符串(甚至NULL为此事)作为的jstring
。相反,我用(* ENV) - &GT; NewStringUTF(ENV,NULL)
以创建一个空的jstring
。
OK, found it.It was a problem with the jstring
parameters. It turns out you cannot pass empty strings (or even NULL for that matter) as a jstring
.Instead I used (*env)->NewStringUTF(env, NULL)
to create a NULL jstring
.
似乎现在的工作确定。
由于这个问题产生的有点高活性,我张贴下面的最终解决方案。请注意, nullString
变量被释放在其范围结束(或当您使用它做):
Since this question generated somewhat a high activity, I'm posting the final solution below. Note that the nullString
variable is being deallocated at the end of its scope (or when you're done using it):
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);
这篇关于NewObject的上呼叫无效的间接引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!