Unicode 国际组件 (ICU)
Unicode(ICU)的国际组件是一组成熟的、广泛使用的开源全球化 API。 ICU 利用 Unicode 庞大的通用区域设置数据存储库(CLDR)作为其数据库,为软件应用程序提供全球化支持。 ICU 可广泛移植,可在所有平台上为应用程序提供相同的结果。
ICU 提供的全球化 API 服务的亮点
- 代码页转换:将文本数据转换为 Unicode 以及几乎任何其他字符集或编码。 ICU 的转换表基于 IBM 在几十年中收集的字符集数据,并且是随处可用的最完整的数据。
- 排序规则:根据特定语言、地区或国家/地区的约定和标准比较字符串。 ICU 的排序规则基于 Unicode 排序规则以及 CLDR 中特定于区域设置的比较规则。
- 格式:根据所选区域设置约定设置数字、日期、时间和货币金额的格式。 这包括将月份和日期名称翻译为所选语言、选择适当的缩写、正确排序字段等。此数据也来自通用区域设置数据存储库。
- 时间计算:除了传统的公历之外,还提供了多种类型的日历。 提供了一组全面的时区计算 API。
- Unicode 支持:ICU 密切跟踪 Unicode 标准,提供对所有 Unicode 字符属性、Unicode 规范化、大小写折叠和其他基本作(由 Unicode 标准所指定)的轻松访问。
- 正则表达式:ICU 的正则表达式完全支持 Unicode,同时提供非常具有竞争力的性能。
- Bidi:支持处理包含从左到右(英语)和从右到左(阿拉伯语或希伯来语)数据的混合文本。
有关详细信息,请访问 ICU 网站:http://site.icu-project.org/
概述
在 Windows 10 创意者更新中,ICU 已集成到 Windows 中,使 C API 和数据可公开访问。
重要
Windows 中的 ICU 版本仅公开 C API。 它不公开任何C++ API。 遗憾的是,由于C++中缺少稳定的 ABI,因此不可能公开C++ API。
有关 ICU C API 的文档,请参阅此处的官方 ICU 文档页:http://icu-project.org/apiref/icu4c/index.html#Module
Windows 中 ICU 库更改的历史记录
版本 1703 (创意者更新)
ICU 库首先添加到此版本中的 Windows 10 OS。 它已添加为:
- 两个系统 DLL:
- icuuc.dll(这是 ICU“通用”库)
- icuin.dll(这是 ICU“i18n”库)
- Windows 10 SDK 中的两个头文件:
- icucommon.h
- icui18n.h
- Windows 10 SDK 中的两个导入库:
- icuuc.lib
- icuin.lib
版本 1709 (Fall Creators Update)
添加了组合头文件 icu.h,其中包含上述两个头文件(icucommon.h 和 icui18n.h)的内容,并将 UCHAR
的类型更改为 char16_t
。
版本 1903 (2019 年 5 月更新)
添加了新的组合 DLL icu.dll,其中包含“common”和“i18n”库。 此外,还向 Windows 10 SDK 添加了新的导入库:icu.lib。
今后,不会向旧标头(icucommon.h 和 icui18n.h)或旧导入库(icuuc.lib 和 icuin.lib)添加新 API。 新 API 将仅添加到组合标头(icu.h)和合并的导入库(icu.lib)。
开始
需要执行三个主要步骤:(Windows 10 创意者更新或更高版本)
应用程序需要面向 Windows 10 版本 1703(创意者更新)或更高版本。
在标头中添加:
#include <icucommon.h> #include <icui18n.h>
在 Windows 10 版本 1709 及更高版本中,应改为包含组合标头:
#include <icu.h>
链接到两个库:
- icuuc.lib
- icuin.lib
在 Windows 10 版本 1903 及更高版本上,应改用组合库:
- icu.lib
然后,可以从所需的库调用任何 ICU C API。 (未公开C++ API。
重要
如果使用旧导入库、icuuc.lib 和 icuin.lib,请确保它们列在伞式库(如 onecoreuap.lib 或 WindowsApp.lib)之前(请参阅下图)。 否则,链接器将链接到 icu.lib,这将导致在运行时尝试加载 icu.dll。 该 DLL 仅从版本 1903 开始存在。 因此,如果用户在版本 1903 Windows 计算机上升级 Windows 10 SDK,应用将无法加载并运行。 有关 Windows 中 ICU 库的历史记录,请参阅 windows 中 ICU 库更改的历史记录。
注意
- 这是“所有平台”的配置。
- 若要使 Win32 应用使用 ICU,他们需要首先调用 CoInitializeEx。 在 Windows 10 版本 1903 及更高版本中,可以使用合并的 ICU 库(icu.dll/icu.lib),可以使用组合库省略 CoInitializeEx 调用。
- ICU API 返回的所有数据都不会与 Windows OS 保持一致,因为此对齐工作仍在进行中。
ICU 示例应用
示例代码片段
下面是一个示例,演示如何在 C++ UWP 应用程序中使用 ICU API。 (它不是完整的独立应用程序,而是调用 ICU 方法的一个示例。
以下小示例假定有一些方法 ErrorMessage,OutputMessage 以某种方式向用户输出字符串。
// On Windows 10 Creators Update, include the following two headers. With Windows 10 Fall Creators Update and later, you can just include the single header <icu.h>.
#include <icucommon.h>
#include <icui18n.h>
void FormatDateTimeICU()
{
UErrorCode status = U_ZERO_ERROR;
// Create a ICU date formatter, using only the 'short date' style format.
UDateFormat* dateFormatter = udat_open(UDAT_NONE, UDAT_SHORT, nullptr, nullptr, -1, nullptr, 0, &status);
if (U_FAILURE(status))
{
ErrorMessage(L"Failed to create date formatter.");
return;
}
// Get the current date and time.
UDate currentDateTime = ucal_getNow();
int32_t stringSize = 0;
// Determine how large the formatted string from ICU would be.
stringSize = udat_format(dateFormatter, currentDateTime, nullptr, 0, nullptr, &status);
if (status == U_BUFFER_OVERFLOW_ERROR)
{
status = U_ZERO_ERROR;
// Allocate space for the formatted string.
auto dateString = std::make_unique<UChar[]>(stringSize + 1);
// Format the date time into the string.
udat_format(dateFormatter, currentDateTime, dateString.get(), stringSize + 1, nullptr, &status);
if (U_FAILURE(status))
{
ErrorMessage(L"Failed to format the date time.");
return;
}
// Output the formatted date time.
OutputMessage(dateString.get());
}
else
{
ErrorMessage(L"An error occured while trying to determine the size of the formatted date time.");
return;
}
// We need to close the ICU date formatter.
udat_close(dateFormatter);
}