我已阅读,在内存中的Java存储字符串作为UTF-16
它使用,但这种情况正在改变。根据JEP 254: Compact Strings,内存中的存储可能很快会使用ISO-8859-1,但是只有在时才会产生比UTF-16更紧凑的存储而不会丢失数据。尽管Java字符串使用基于UTF-16的公共接口(不管它们的内存中存储是否使用ISO-8859-1)。所以只是假装他们总是UTF-16。
当我有一个Java字符串被发送到C++客户端,我应该假设它是UTF-8或UTF-16吗?
你也不能假设。你必须看看实际的SOAP数据。 SOAP使用XML,并且XML可以使用任何编码创建者想要的字符,只要它在XML prolog中声明它(如果它不是UTF-8,它是XML中最常用的编码)。不要假设,知道你在做什么。如果您使用的是SOAP库,则受限于其选择用于其内存字符串的任何编码。
当我收到从Java一个字符串,然后将其插入std::wstring
,没有任何类型转换的C++客户端使用Windows-1252
代码页。
这是不太可能的,因为std::wstring
在Windows上使用UTF-16,并且Java字符串也是UTF-16(用于所有意图和目的)。您必须错误地转换您的字符串。请edit your question显示您的实际代码。
接收和转换Unicode字符串MultiByteToWideChar
是否正确?
IF你有一个8位ANSI字符串开始与(char*
或std::string
),然后是。但是,当与Java直接交互(通过JNI/JNA)或std::wstring
时,情况不应该如此。所以这让我想知道是否在基于8位ANSI字符串而不是16位Unicode字符串的C++端使用SOAP实现。
虽然,我调用Windows函数(SetComputerNameExW
)是指接受Unicode的,当我传递一个从Java通过SOAP收到的字符串(我特意重新编码字符串作为UTF-8,而调试)请求,并将它,解码为对C++侧UTF-8的值传递给SetComputerNameExW
系统之后启动一个重新启动
不能在UTF-8字符串传递给SetComputerNameExW()
,代码甚至不会编译,除非你使用无效的类型转换强制它。您必须改为传递一个UTF-16字符串。
但只重命名机器的第一个字符(即,如果我的字符串为ThisIsATëst
,那么机器将重命名为T
)。
这意味着某些事情对您的转换非常不利。无论你认为你传递到SetComputerNameExW()
是不是什么实际上被传递,它没有正确格式化,这就是为什么SetComputerNameExW()
只拿起第一个字符。
但是,再次,这是一种情况,您没有显示您的实际SOAP数据或代码,所以没有人可以告诉你为什么字符串未被正确格式化。
是否有一个特定的Unicode格式必须用于这些Windows API调用?
的Win32 API中只支持两种类型的字符串:
不能使用UTF-8 (除非是很少的情况),所以你必须将任何UTF-8数据转换为其他格式之一(最好是UTF-16,因为之间的转换UTF无损,Windows核心基于UTF-16)。
_“...和磁盘上的UTF-8”_这通常取决于您使用的IO API的编码。 –
Windows使用UTF-16LE。如果您在Java中使用UTF-16字符串,只需将它们传递给Windows即可。如果您将它们保存为UTF-8,则在将它们读入Windows程序时,您需要将它们转换为UTF-16LE。 'MultiByteToWideChar'可以从UTF-8转换为UTF-16,所以C++ 11的标准功能可以。 –