gpt4 book ai didi

java - 通过 JNI 将双字节 (WCHAR) 字符串从 C++ 传递到 Java

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:19:18 27 4
gpt4 key购买 nike

我有一个 Java 应用程序,它通过 JNI 使用 C++ DLL。 DLL 的一些方法采用字符串参数,其中一些方法返回也包含字符串的对象。

目前DLL不支持Unicode,所以字符串处理比较简单:

  • Java 调用 String.getBytes() 并将生成的数组传递给 DLL,DLL 将数据简单地视为 char*。
  • DLL 使用 NewStringUTF() 从 const char* 创建 jstring。

我现在正在修改 DLL 以支持 Unicode,切换到使用 TCHAR 类型(当定义 UNICODE 时使用 Windows 的 WCHAR 数据类型)。修改 DLL 进行得很顺利,但我不确定如何修改代码的 JNI 部分。

我现在唯一能想到的是:

  • Java 调用 String.getBytes(String charsetName) 并将生成的数组传递给 DLL,DLL 将数据视为 wchar_t*。
  • DLL 不再创建字符串,而是将原始字符串数据传递给 jbyteArrays。 Java 使用 String(byte[] bytes, String charsetName) 构造函数来实际创建 String。

此方法的唯一问题是我不确定要使用什么字符集名称。 WCHAR 的长度为 2 个字节,所以我很确定它是 UTF-16,但在 Java 端有 3 种可能性。 UTF-16、UTF-16BE 和 UTF-16LE。我还没有找到任何文档来告诉我字节顺序是什么,但我可能可以通过一些快速测试来弄清楚。

有没有更好的方法?如果可能的话,我想继续在 DLL 中构建 jstring 对象,因为这样我就不必修改这些方法的任何用法。但是,NewString JNI 方法不采用字符集标识符。

最佳答案

This answer建议不能保证 WCHARS 的字节顺序......

因为你在 Windows 上,你可以尝试 <a href="http://msdn.microsoft.com/en-us/library/aa450989.aspx" rel="noreferrer noopener nofollow">WideCharToMultiByte</a>将 WCHAR 转换为 UTF-8,然后使用您现有的 JNI 代码。

您需要小心使用 WideCharToMultiByte由于缓冲区溢出的可能性 lpMultiByteStr范围。要解决这个问题,您应该调用该函数两次,首先是 lpMultiByteStr设置为 NULLcbMultiByte设置为零 - 这将返回所需 lpMultiByteStr 的长度缓冲而不试图写入它。获得长度后,您可以分配所需大小的缓冲区并再次调用该函数。

示例代码:

int utf8_length;

wchar_t* utf16 = ...;

utf8_length = WideCharToMultiByte(
CP_UTF8, // Convert to UTF-8
0, // No special character conversions required
// (UTF-16 and UTF-8 support the same characters)
utf16, // UTF-16 string to convert
-1, // utf16 is NULL terminated (if not, use length)
NULL, // Determining correct output buffer size
0, // Determining correct output buffer size
NULL, // Must be NULL for CP_UTF8
NULL); // Must be NULL for CP_UTF8

if (utf8_length == 0) {
// Error - call GetLastError for details
}

char* utf8 = ...; // Allocate space for UTF-8 string

utf8_length = WideCharToMultiByte(
CP_UTF8, // Convert to UTF-8
0, // No special character conversions required
// (UTF-16 and UTF-8 support the same characters)
utf16, // UTF-16 string to convert
-1, // utf16 is NULL terminated (if not, use length)
utf8, // UTF-8 output buffer
utf8_length, // UTF-8 output buffer size
NULL, // Must be NULL for CP_UTF8
NULL); // Must be NULL for CP_UTF8

if (utf8_length == 0) {
// Error - call GetLastError for details
}

关于java - 通过 JNI 将双字节 (WCHAR) 字符串从 C++ 传递到 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/870414/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com