如何将C ++中的wchar wstring转换为更好的支持?

时间:2011-11-25 07:08:21

标签: android c++ android-ndk

我是一名Java开发人员,我已经开始编译Android NDK编译具有wchar和wstring等的C ++类的问题。在检查是否有任何内容可能支持这些之后,我的发现到目前为止表明在NDK上没有完全支持这些。这意味着我需要在源代码中更改它们。怎么可以做到这一点?感谢

2 个答案:

答案 0 :(得分:1)

最好的方法是尽可能在Java中重写:)

但是wchar和朋友基本上只是“具有16位而不是8位字符的零终止数组”。微软库通过使用并行版本的strcpy()/ wstrcpy(),strlen()/ wstrlen()等来解决问题。确定使用wchar的位置应该相当简单,并实现您可能需要的几个简单函数,不应该吗?

答案 1 :(得分:1)

好的,除了标记副本外,我还发现了这篇有趣的文章:

TL; DR 我们选择从Android开源项目中的JNI的Android实现中提取核心宽/窄转换例程,以便转换完全以本机代码运行

  

宽字符串和窄字符串转换

     

由于存在多种方法和标准,移植应用程序时这是一个非常复杂的问题。 Windows Mobile(Windows CE)标准化为每个字符单元UTF-16的两个字节,并且极少例外,ANSI或每个字符单元本机API的一个字节被消除。 C#语言和.NET Compact Framework也使用UTF-16。

     

Linux和Android本机API依赖于每个字符单元的单字节,空终止字符串。 Linux上的宽C ++字符是每个字符4个字节,而Microsoft平台上每个字符单元2个字节。一种效果是使所有宽字符串的长度加倍,包括前面带有L字符的字符串文字。

     

一种可能性是将包括代理对的UTF-16转换为UTF-8多字节字符串,每个字符可能需要一到四个字节,并且可以包含嵌入的零字节。 Java Native Interface(JNI)提供了将Java UTF-16转换为“Modified”UTF-8的例程。修改导致一个窄字符串,不包含嵌入的零,只有字符串末尾的零。另一个修改是将四字节UTF-16代理对转换为两个UTF-8字符,每个字节长三个字节而不是一个UTF-8字符,长度为四个字节。

     

使用JNI例程在宽字符串和窄字符串之间进行转换的最终结果是宽UTF-16字符串格式与Java和Windows Mobile(CE)兼容,并且窄的Modified UTF-8字符串与Android /兼容Linux OS API和C运行时库。

     Android C运行时库(Bionic)包含一个wchar.h来实现wcslen,wcscpy等函数,但是如标题中的注释中所述,Android C中没有实现实际的宽字符函数运行时库。我们通过使用GNU C ++编译器选项“-fshort-wchar”来解决这个问题,该选项强制编译器将宽字符视为两个字节而不是四个字节。这使得L“string”文字每个字符两个字节并与UTF-16兼容。我们从Wine开源项目中提取了实际的宽字符运行时库。

     

可以使用Android中提供的JNI在本机C ++范围和窄字符串之间进行转换。这涉及到Java环境的往返,因此效率不高。 我们选择从Android开源项目中的JNI的Android实现中提取核心宽/窄转换例程,以便转换完全以本机代码运行