gpt4 book ai didi

android - NewObject 调用的间接引用无效

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:18:56 25 4
gpt4 key购买 nike

好的,下面是 native 代码。我试图从中返回一个 FilePermissionInfo 数组,其中填充了 stat() 返回的一些数据。问题是第一次调用 NewObject 时出现以下错误:

06-15 20:25:17.621: W/dalvikvm(2287): Invalid indirect reference 0x40005820 in decodeIndirectRef 06-15 20:25:17.621: E/dalvikvm(2287): 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, 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,那么它工作正常。

最佳答案

好的,找到了。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);

关于android - NewObject 调用的间接引用无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11055609/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com