Международные компоненты для Юникода (ICU)

Международные компоненты для Юникода (ICU) — это зрелый и широко используемый набор API глобализации с открытым кодом. ICU использует обширный репозиторий общих языковых стандартов Юникода (CLDR) в качестве библиотеки данных, обеспечивая поддержку глобализации для программных приложений. ICU широко переносится и дает приложениям одинаковые результаты на всех платформах.

Основные сведения о службах API глобализации, предоставляемых ICU

  • Преобразование кодовых страниц. Преобразуйте текстовые данные в Юникод или из нее, а также практически любую другую кодировку или кодировку. Таблицы преобразования ICU основаны на данных наборов символов, собранных IBM в течение многих десятилетий, и являются наиболее полными, доступными в любом месте.
  • Параметры сортировки. Сравнение строк в соответствии с соглашениями и стандартами определенного языка, региона или страны. Параметры сортировки ICU основаны на алгоритме сортировки Юникод, а также на правилах сравнения для конкретного языкового стандарта из CLDR.
  • Форматирование. Форматируйте числа, даты, время и денежные суммы в соответствии с соглашениями выбранного языкового стандарта. Сюда входит перевод названий месяцев и дней на выбранный язык, выбор соответствующих сокращений, правильное упорядочивание полей и т. д. Эти данные также поступают из репозитория общих данных языкового стандарта.
  • Вычисления времени. Несколько типов календарей предоставляются за пределами традиционных григорианских. Предоставляется подробный набор API вычислений часовых поясов.
  • Поддержка Юникода. ICU внимательно отслеживает стандарт Юникода, обеспечивая простой доступ ко всем свойствам символов Юникода, нормализации Юникода, свертыванием регистра и другим фундаментальным операциям, указанным в стандарте Юникода.
  • Регулярные выражения. Регулярные выражения ICU полностью поддерживают Юникод, обеспечивая при этом высокую конкурентоспособность.
  • Bidi: поддержка обработки текста, содержащего смесь данных слева направо (английский) и справа налево (арабский или иврит).

Дополнительные сведения см. на веб-сайте ICU: http://site.icu-project.org/

Общие сведения

В Windows 10 Creators Update ICU был интегрирован в Windows, что сделало API C и данные общедоступными.

Важно!

Версия ICU в Windows предоставляет только API C. Он не предоставляет ни один из API C++. К сожалению, невозможно предоставить доступ к API C++ из-за отсутствия стабильного ABI в C++.

Документацию по API C ICU см. на официальной странице документации по ICU здесь: http://icu-project.org/apiref/icu4c/index.html#Module

Журнал изменений в библиотеке ICU в Windows

Версия 1703 (Creators Update)

Библиотека ICU была впервые добавлена в ос Windows 10 в этой версии. Он был добавлен в виде:

  • Две системные библиотеки DLL:
    • icuuc.dll (это "общая" библиотека ICU)
    • icuin.dll (это библиотека ICU i18n)
  • Два файла заголовков в пакете SDK для Windows 10:
    • icucommon.h
    • icui18n.h
  • Две библиотеки импорта в пакете SDK для Windows 10:
    • icuuc.lib
    • icuin.lib

Версия 1709 (Fall Creators Update)

Добавлен объединенный файл заголовка icu.h, который содержит содержимое обоих указанных выше файлов заголовков (icucommon.h и icui18n.h), а также изменяет тип UCHAR на char16_t.

Версия 1903 (обновление за май 2019 г.)

Добавлена новая объединенная библиотека DLL ,icu.dll, которая содержит библиотеки common и i18n. Кроме того, в пакет SDK для Windows 10 добавлена новая библиотека импорта: icu.lib.

В дальнейшем новые API не будут добавлены в старые заголовки (icucommon.h и icui18n.h) или в старые библиотеки импорта (icuuc.lib и icuin.lib). Новые API будут добавлены только в объединенный заголовок (icu.h) и объединенную библиотеку импорта (icu.lib).

Приступая к работе

Необходимо выполнить три main шага: (Windows 10 Creators Update или более поздней версии).

  1. Приложение должно быть предназначено Windows 10 версии 1703 (Creators Update) или более поздней.

  2. Добавьте в заголовки:

    #include <icucommon.h>
    #include <icui18n.h>
    

    В Windows 10 версии 1709 и более поздних следует включить объединенный заголовок:

    #include <icu.h>
    
  3. Ссылка на две библиотеки:

    • icuuc.lib
    • icuin.lib

    В Windows 10 версии 1903 и выше следует использовать объединенную библиотеку:

    • icu.lib

Затем можно вызвать любой API C ICU из этих библиотек. (API C++ не предоставляются.)

Важно!

Если вы используете устаревшие библиотеки импорта icuuc.lib и icuin.lib, убедитесь, что они перечислены перед библиотеками зонтичных, например onecoreuap.lib или WindowsApp.lib, в параметре Компоновщик дополнительных зависимостей (см. изображение ниже). В противном случае компоновщик будет ссылаться на icu.lib, что приведет к попытке загрузить icu.dll во время выполнения. Эта библиотека DLL присутствует только начиная с версии 1903. Таким образом, если пользователь обновит пакет SDK для Windows 10 на компьютере с Windows до версии 1903, приложение не сможет загрузиться и запуститься. Журнал библиотек ICU в Windows см. в статье Журнал изменений в библиотеке ICU в Windows.

Пример icu

Примечание

  • Это конфигурация для "Все платформы".
  • Чтобы приложения Win32 использовали ICU, им необходимо сначала вызвать CoInitializeEx . В Windows 10 версии 1903 и выше, где доступна объединенная библиотека ICU (icu.dll/icu.lib), вызов CoInitializeEx можно опустить с помощью объединенной библиотеки.
  • Не все данные, возвращаемые API ICU, будут соответствовать ОС Windows, так как эта работа по выравниванию еще выполняется. 

Пример приложения ICU

Пример фрагмента кода

Ниже приведен пример, демонстрирующий использование API-интерфейсов ICU из приложения UWP на C++. (Оно не предназначено для полного автономного приложения, скорее это просто пример вызова метода 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);
}