几个月前,我编写了一个使用JNI来封装C API的Java API。 C API使用char字符串,我使用GetStringUTFChars从Java字符串创建C字符串。
我忽略了思考非ASCII字符可能出现的问题。
从那时起,C API的创建者为每个需要或返回wchar_t字符串的C函数创建了宽字符等价物。我想更新我的Java API以使用这些宽字符函数,并克服我对非ASCII字符的问题。
研究过JNI文档之后,我对使用GetStringChars或GetStringRegion方法的相对优点感到有些困惑。
我知道wchar_t字符的大小因Windows和Linux而异,并且不确定创建C字符串的最有效方法(之后将它们转换回Java字符串)。
这是我目前的代码,我认为每个字符创建一个包含两个字节的字符串:
int len;
jchar *Src;
len = (*env)->GetStringLength(env, jSrc);
printf("Length of jSrc is %d\n", len);
Src = (jchar *)malloc((len + 1)*sizeof(jchar));
(*env)->GetStringRegion(env, jSrc, 0, len, Src);
Src[len] = '\0';
但是,当wchar_t的大小与jchar不同时,需要进行修改。
答案 0 :(得分:1)
C API创建者是不是愿意退一步并重新实现 UTF-8 ? :)你的工作必然会消失,只需要GetStringUTFChars
/ NewStringUTF
。
jchar
的类型定义为unsigned short
,相当于 UTF-16 的JVM char
。因此,在wchar_t
为2字节 UTF-16 的Windows上,您可以取消您提供的代码。只需复制原始字节,相应地进行分配。完成C API调用后,不要忘记释放。与NewString
补充以转换回jstring。
我所知道的唯一其他wchar_t
大小是4字节(最突出的是Linux) UTF-32 。问题出在这里: UTF-32不仅仅是UTF-16以某种方式填充到4个字节。分配双倍的内存量只是一个开始。有一个实质性的转换,like this one which seems to be sufficiently free。
但是如果你没有那么多表现并且愿意放弃在Windows上的普通内存复制,我建议将jstring
转到UTF-8(这是JNI本身提供的文档化功能)然后UTF-8到UTF-16或UTF-32取决于sizeof(wchar_t)
。关于每个平台给出的字节顺序和UTF编码,不会有任何假设。你好像在乎它,我发现你正在检查sizeof(jchar)
,对于大部分可见宇宙来说,它是2:)