Unicode 的國際元件 (ICU)
Unicode (ICU) 的國際元件是一組成熟的、廣泛使用的開放原始碼全球化 API。 ICU 利用 Unicode 龐大的通用地區設定資料存放庫 (CLDR) 作為其資料庫,為軟體應用程式提供全球化支援。 ICU 可廣泛移植,可在所有平臺上提供相同的結果給應用程式。
ICU 所提供全球化 API 服務的亮點
- 代碼頁轉換:將文字數據轉換成 Unicode,以及幾乎任何其他字元集或編碼。 ICU 的轉換數據表是以 IBM 在數十年中收集的字元集數據為基礎,而且是隨處提供的最完整數據。
- 定序:根據特定語言、地區或國家/地區的慣例和標準比較字串。 ICU 的定序是以 Unicode 定序演算法為基礎,加上 CLDR 的地區設定特定比較規則。
- 格式化:根據所選地區設定慣例,格式化數位、日期、時間和貨幣金額。 這包括將月份和日期名稱翻譯成選取的語言、選擇適當的縮寫、正確排序欄位等等。此數據也來自 Common Locale Data Repository。
- 時間計算:除了傳統的公曆之外,還提供多種行事曆類型。 提供一組完整的時區計算 API。
- Unicode 支援:ICU 會密切追蹤 Unicode 標準,輕鬆存取所有 Unicode 字元屬性、Unicode 正規化、大小寫摺疊和其他基本作業,如 Unicode Standard所指定。
- 正則表示式:ICU 的正則表示式完全支援 Unicode,同時提供非常具競爭力的效能。
- Bidi:支持處理含有左至右(英文)和由右至左(阿拉伯文或希伯來文)數據的混合文字。
如需詳細資訊,您可以流覽 ICU 網站:http://site.icu-project.org/
概述
在 Windows 10 Creators Update 中,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 (Creators Update)
ICU 連結庫第一次新增至此版本的 Windows 10 OS。 它已新增為:
- 兩個系統 DLL:
- icuuc.dll (這是 ICU “common” 連結庫)
- 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。
接下來,不會將任何新的 API 新增至舊標頭 (icucommon.h 和 icui18n.h) 或舊匯入 libs (icuuc.lib 和 icuin.lib)。 新的 API 只會新增至合併標頭 (icu.h) 和合併匯入 lib (icu.lib)。
開始
有三個主要步驟要遵循:(Windows 10 Creators Update 或更新版本)
您的應用程式需要以 Windows 10 版本 1703(Creators Update) 或更高版本為目標。
在標頭中新增:
#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);
}