首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将ICU4C字节转换为java字符

将ICU4C字节转换为java字符
EN

Stack Overflow用户
提问于 2011-02-22 19:24:18
回答 2查看 947关注 0票数 1

我正在通过JNI访问一个ICU4C函数,它返回一个UChar *(即unicode字符数组).通过将UChar数组的每个成员等效为我创建的本地jbyte[]数组,可以将其转换为Java,然后使用env->SetByteArrayRegion()函数将其返回给jbyte[].现在我有了Java中的Byte[]数组,但这几乎是胡说八道。奇怪的符号充其量..。我不知道问题出在哪里.我在处理unicode字符如果这重要的话..。如何正确地将byte[]转换为java中的char[]?有些东西被映射的不对..。下面是代码的一个片段:

- JNI代码(修改打火机使其更短)

代码语言:javascript
复制
static jint testFunction(JNIEnv* env, jclass c, jcharArray srcArray, jbyteArray destArray) {

    jchar* src = env->GetCharArrayElements(srcArray, NULL);
    int n = env->getArrayLength(srcArray);

    UChar *testStr = new UChar[n];
    jbyte destChr[n];

    //calling ICU4C function here    
    icu_function (src, testStr);   //takes source characters and returns UChar*

    for (int i=0; i<n; i++)
        destChr[i] = testStr[i];   //is this correct?

    delete testStr;
    env->SetByteArrayRegion(destArray, 0, n, destChr);
    env->ReleaseCharArrayElements(srcArray, src, JNI_ABORT);

    return (n); //anything for now
}

- Java代码--字符串wohoo = "ABCD bal bla bla";char[] myChars = wohoo.toCharArray();

代码语言:javascript
复制
byte[] myICUBytes = new byte[myChars.length];
int value = MyClass.testFunction (myChars, myICUBytes);

System.out.println(new String(myICUBytes)) ;// produces gibberish & weird symbols

我也试过了:System.out.println(新字符串(myICUBytes,Charset.forName(“UTF-16”)),它也很有趣.

请注意,ICU函数确实返回了UChar *.中的适当unicode字符。在转换到jbyteArray和Java之间的某个地方正在搞砸.

帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-22 21:40:09

代码语言:javascript
复制
destChr[i] = testStr[i];   //is this correct?

这看起来是个问题,好吧。

JNI类型

代码语言:javascript
复制
byte   jbyte    signed 8 bits
char   jchar    unsigned 16 bits

ICU4C类型

如果UChar宽为16位,则将其定义为wchar_t;始终假定为无符号。 如果wchar_t不是16位宽,那么将UChar定义为uint16_t或char16_t,因为GCC >=4.4可以处理UTF16字符串文本。这使得UChar的定义依赖于平台,但允许直接字符串类型与具有16位wchar_t类型的平台兼容。

因此,除了icu_function可能做的任何事情之外,您还试图将一个16位值放入8位宽的类型中。

如果必须使用Java字节数组,我建议通过将代码转换为Unicode编码将其转换为8位char类型。

转译一些C代码

代码语言:javascript
复制
UChar *utf16 = (UChar*) malloc(len16 * sizeof(UChar));
//TODO: fill data
// convert to UTF-8
UConverter *encoding = ucnv_open("UTF-8", &status);
int len8 = ucnv_fromUChars(encoding, NULL, 0, utf16, len16, &status);
char *utf8 = (char*) malloc(len8 * sizeof(char));
ucnv_fromUChars(encoding, utf8, len8, utf16, len16, &status);
ucnv_close(encoding);
//TODO: char to jbyte

然后,您可以使用new String(myICUBytes, "UTF-8")将其转换为Java。

我使用了UTF-8,因为它已经在我的示例代码中了,您不必担心endianness。酌情将我的C转换为C++。

票数 1
EN

Stack Overflow用户

发布于 2011-02-22 19:28:32

你考虑过使用ICU4J吗?

此外,在将字节转换为字符串时,需要指定字符编码。我对图书馆不熟悉,所以我不能进一步建议你,但也许这是"UTF-16“或类似的?

哦,还值得注意的是,您可能只是收到显示错误,因为您要打印的终端没有使用正确的字符集和/或没有正确的符号可用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5082853

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档