java - 在从 Java SOAP 接收的 Windows 调用 (C++) 中使用 Unicode 文本

标签 java c++ windows soap unicode

我正在使用带有 C++ 的 gSoap 来发送和接收来自 Java 的 Web 服务调用。 Java 对字符的看法与 C/C++ 对字符的看法之间的差异似乎正在造成严重破坏,不同的代码页也是如此。这个问题有几个不同的部分。

  1. 我读到 Java 在内存中以 UTF-16 格式存储字符串,在磁盘中以 UTF-8 格式存储字符串。当我将一个 Java 字符串发送到 C++ 客户端时,我应该假设它是 UTF-8 还是 UTF-16?
  2. 当我从 Java 接收到一个字符串并将其插入 std::wstring 时,C++ 客户端使用 Windows-1252 代码页,没有任何类型的转换.接收和转换 unicode 字符串 MultiByteToWideChar 的函数是否正确?
  3. 尽管我正在调用的 Windows 函数 (SetComputerNameExW) 旨在接受 Unicode,但当我传入通过 SOAP 从 Java 接收的字符串时(我专门将该字符串重新编码为 UTF -8 调试时)在 C++ 端请求并将其解码为 UTF-8,在将值传递给 SetComputerNameExW 后,系统启动重启但仅将机器重命名为第一个字符(即,如果我的string 是 ThisIsATëst,则机器将重命名为 T)。这些 Windows API 调用是否必须使用特定的 Unicode 格式?

非常感谢任何帮助!谢谢!

最佳答案

I have read that Java stores strings in memory as UTF-16

曾经是,但这正在改变。每JEP 254: Compact Strings ,内存存储可能很快会改用 ISO-8859-1,但仅当它会导致比 UTF-16 更紧凑的存储而不会丢失数据。尽管 Java 字符串使用基于 UTF-16 的公共(public)接口(interface)(无论它们的内存存储是否使用 ISO-8859-1)。所以只是假装它们总是UTF-16。

When I have a Java string being sent to the C++ client, should I assume that it is UTF-8 or UTF-16?

您不能假设任何一种编码。您必须查看实际的 SOAP 数据。 SOAP 使用 XML,而 XML 可以使用创建者想要的任何字符编码,只要它在 XML prolog 中声明编码(如果它不是 UTF-8,这是 XML 中最常用的编码)。不要假设,知道你在做什么。如果您使用的是 SOAP 库,您将受到它选择用于其内存中字符串的任何编码的限制。

When I receive a string from Java and just insert it into a std::wstring, without any sort of conversion the C++ client uses the Windows-1252 code page.

这不太可能,因为 std::wstring 在 Windows 上使用 UTF-16,而 Java 字符串也是 UTF-16(出于所有意图和目的)。您必须错误地转换字符串。请edit your question显示您的实际代码。

Is the correct function to receive and convert the unicode string MultiByteToWideChar?

如果您有一个 8 位字符串 ANSI 开头(char*std::string),那么是。但是,当直接与 Java(通过 JNI/JNA)或 std::wstring 交互时,情况就不应该如此。所以我想知道您是否在 C++ 端使用基于 8 位 ANSI 字符串而不是 16 位 Unicode 字符串的 SOAP 实现。

Although the Windows function that I am calling (SetComputerNameExW) is meant to accept Unicode, when I pass in the string that is received from Java via SOAP (I specifically re-encode the string as UTF-8 while debugging) request and decode it as UTF-8 on the C++ side, after passing the value to SetComputerNameExW the system initiates a reboot

您不能将 UTF-8 字符串传递给 SetComputerNameExW(),代码甚至不会编译,除非您使用无效的类型转换来强制执行它。您必须改为传递 UTF-16 字符串。

but only renames the machine to the first character (ie, if my string is ThisIsATëst, then the machine will rename to T).

这意味着您的转化出现了非常糟糕的情况。无论您认为传递给 SetComputerNameExW() 的内容都不是实际传递的内容,它的格式不正确,这就是为什么 SetComputerNameExW() 只选取第一个字符。

但是,在这种情况下,您还没有显示实际的 SOAP 数据或代码,因此没有人能告诉您为什么字符串格式不正确。

Is there a specific Unicode format that has to be used for these Windows API calls?

Win32 API 只支持两种类型的字符串:

  • 本地化的 ANSI 字符串

  • UTF-16 字符串

您根本不能使用 UTF-8(极少数​​情况除外),因此您必须将任何 UTF-8 数据转换为其他格式之一(最好是 UTF-16,因为 UTF 之间的转换会丢失-less,Windows 核心无论如何都是基于 UTF-16 的)。

关于java - 在从 Java SOAP 接收的 Windows 调用 (C++) 中使用 Unicode 文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42841641/

相关文章:

c++ - 堆栈分配类发生不需要的析构函数调用 - C++

windows - 无法为 Windows 构建 OpenH264.lib

c# - 代表文件路径的 guid 字符串是什么?

java - 如何在android中解析JSONArray

c++ - 将 Windows 商店中的私钥转换为 PEM(用于 OpenSSL)

java - 二进制字符串转十进制的函数

c++ - NS-3 自载网络 : How to implement simple intersection scenario?

windows - 批处理循环错误 - 仅复制 1 个文件

java - AsyncTask 中通过代码旋转屏幕崩溃

java - 在 map 上显示线串的方向 - 在 map 上自动缩放