gpt4 book ai didi

java - JNI - 将 UChar 类型映射到

转载 作者:行者123 更新时间:2023-12-02 08:23:34 27 4
gpt4 key购买 nike

我有一个 JNI 函数,它返回一个 UChar 数组(来自 ICU4C 库),我想将其转换为 Java 字符数组,以便我可以从 Java 调用它。我不确定问题出在哪里,因为每当我访问这个 JNI 函数时,一切都会崩溃并挂起,但我在任何地方都没有收到错误消息,包括在 logcat 中......非常难以调试!

UChar 数组可以直接映射到 jcharArray 类型吗?另外,我可以将它用作返回类型吗?或者我可以将其作为 JNI 函数随后填充的参数传递吗?

这里是我想做的事情的一个 fragment :

static jint testFunction(JNIEnv* env, jclass c, jobject obj, jcharArray chsArray,
int offset, int len, jcharArray dstArray) {

jchar* dst = env->GetCharArrayElements(dstArray, NULL);

if (dst != NULL) {

UChar *str = new UChar[len];

//populate str here from an ICU4C function

for (int i=0; i<len; i++)
dst[i] = str[i]; //this might be the problematic piece of code (can I issue an assignment like this?)
}
}

env->ReleaseCharArrayElements(dstArray, dst, 0);

}

感谢任何帮助!

谢谢

最佳答案

JNI 确实令人头疼。从表面上看,您的功能看起来不错。

首先,我注意到您没有使用 offset - 这是一种代码味道。

其次,您没有释放 UChar 数组。

第三,C 函数或赋值循环可能超出数组范围。

<小时/>

为了帮助定位像这样的突然崩溃,我成功地使用了一个很好的老式 print 语句与控制台结合使用。

首先,我向 JNIGlobal 类添加了一个 println 方法:

/** Print text or ASCII byte array prefixed with "JNI: ". Primarily for native code to output to the Java console. */
static public void println(Object val) {
if(val instanceof byte[]) { byte[] ba=(byte[])val; val=new String(ba,0,ba.length); }
System.out.println("JNI: "+val);
}

然后我在我的C代码中添加了相应的方法:

void println(JNIEnv *jep, byte *format,...) {
va_list vap;
byte txt[5001];
jsize txtlen;
jclass eCls;
jint mId;
jbyteArray jText;

va_start(vap,format); vsprintf(txt,format,vap); va_end(vap);
txtlen=(long)strlen(txt);

if((eCls=(*jep)->FindClass(jep,"<your/package/here/JNIGlobal"))==0) {
printf("JNI: Global class not found (Error Text: %s)\n",txt);
return; /* give up */
}
if((mId=(*jep)->GetStaticMethodID(jep,eCls,"println","(Ljava/lang/Object;)V"))==0) {
printf("JNI: Global println method not found (Error Text: %s)\n",txt);
return; /* give up */
}
jText=(*jep)->NewByteArray(jep,txtlen);
(*jep)->SetByteArrayRegion(jep,jText,0,txtlen,(void*)txt);
(*jep)->CallStaticVoidMethod(jep,eCls,mId,jText);
}

然后我只需在源代码的每一行调用 println(env,"Some formatted output") 来查看它走了多远。在我的环境(AS/400)中,当 JVM 在交互式运行期间崩溃时,我只剩下控制台 - 您可能需要在 Java 代码中添加短暂的延迟,以确保在控制台消失之前看到输出。

所以对你来说,就像这样:

static jint testFunction(JNIEnv* env, jclass c, jobject obj,
jcharArray chsArray, int offset, int len, jcharArray dstArray) {

/**/println("** testFunction 1");
jchar* dst = env->GetCharArrayElements(dstArray, NULL);

/**/println("** testFunction 2");
if (dst != NULL) {
/**/println("** testFunction 3");
UChar *str = new UChar[len];
/**/println("** testFunction 4");

//populate str here from an ICU4C function

/**/println("** testFunction 5");
for (int i=0; i<len; i++)
dst[i] = str[i]; //this might be the problematic piece of code (can I issue an assignment like this?)
}
/**/println("** testFunction 6");
}

env->ReleaseCharArrayElements(dstArray, dst, 0);
/**/println("** testFunction 7");
}

关于java - JNI - 将 UChar 类型映射到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5009170/

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