Componentes internacionales para Unicode (ICU)

International Components for Unicode (ICU) es un conjunto maduro y ampliamente usado de API de globalización de código abierto. ICU utiliza el amplio repositorio de datos de configuración regional común (CLDR) de Unicode como biblioteca de datos, lo que proporciona compatibilidad de globalización con aplicaciones de software. ICU es ampliamente portátil y proporciona a las aplicaciones los mismos resultados en todas las plataformas.

Aspectos destacados de los servicios de GLOBALIZATION API proporcionados por ICU

  • Conversión de página de códigos: convierta datos de texto en Unicode o desde ellos y casi cualquier otro juego de caracteres o codificación. Las tablas de conversión de ICU se basan en los datos de conjuntos de caracteres recopilados por IBM durante muchas décadas, y es el más completo disponible en cualquier lugar.
  • Intercalación: compare cadenas según las convenciones y estándares de un idioma, región o país determinados. La intercalación de ICU se basa en el algoritmo de intercalación Unicode más las reglas de comparación específicas de la configuración regional de CLDR.
  • Formato: dar formato a números, fechas, horas y importes de moneda según las convenciones de una configuración regional elegida. Esto incluye traducir los nombres de mes y día al idioma seleccionado, elegir las abreviaturas adecuadas, ordenar los campos correctamente, etc. Estos datos también proceden del repositorio de datos de configuración regional común.
  • Cálculos de tiempo: se proporcionan varios tipos de calendarios más allá del gregoriano tradicional. Se proporciona un conjunto exhaustivo de API de cálculo de zona horaria.
  • Compatibilidad con Unicode: ICU realiza un seguimiento del estándar Unicode, lo que proporciona acceso sencillo a todas las muchas propiedades de caracteres Unicode, Normalización Unicode, Plegado de mayúsculas y minúsculas y otras operaciones fundamentales, tal y como especifica el estándar Unicode.
  • Expresión regular: las expresiones regulares de ICU admiten completamente Unicode, a la vez que proporcionan un rendimiento muy competitivo.
  • Bidi: compatibilidad con el control de texto que contiene una combinación de datos de izquierda a derecha (inglés) y de derecha a izquierda (árabe o hebreo).

Para obtener más información, puede visitar el sitio web de ICU: http://site.icu-project.org/

Información general

En Windows 10 Creators Update, ICU se integra en Windows, lo que hace que las API de C y los datos sean accesibles públicamente.

Importante

La versión de ICU en Windows solo expone las API de C. No expone ninguna de las API de C++. Desafortunadamente, es imposible exponer nunca las API de C++ debido a la falta de una ABI estable en C++.

Para obtener documentación sobre las API de C de ICU, consulte la página de documentación oficial de ICU aquí: http://icu-project.org/apiref/icu4c/index.html#Module

Historial de cambios en la biblioteca de ICU en Windows

Versión 1703 (Creators Update)

La biblioteca de ICU se agregó por primera vez al sistema operativo Windows 10 en esta versión. Se agregó como:

  • Dos archivos DLL del sistema:
    • icuuc.dll (esta es la biblioteca "común" de ICU)
    • icuin.dll (esta es la biblioteca ICU "i18n")
  • Dos archivos de encabezado en el SDK de Windows 10:
    • icucommon.h
    • icui18n.h
  • Dos bibliotecas de importación en el SDK de Windows 10:
    • icuuc.lib
    • icuin.lib

Versión 1709 (Fall Creators Update)

Se agregó un archivo de encabezado combinado, icu.h, que contiene el contenido de ambos archivos de encabezado anteriores (icucommon.h e icui18n.h), y también cambia el tipo de UCHAR a char16_t.

Versión 1903 (actualización de mayo de 2019)

Se agregó un nuevo archivo DLL combinado, icu.dll, que contiene las bibliotecas "common" y "i18n". Además, se agregó una nueva biblioteca de importación al SDK de Windows 10: icu.lib.

En el futuro, no se agregarán nuevas API a los encabezados antiguos (icucommon.h e icui18n.h) o a las bibliotecas de importación antiguas (icuuc.lib e icuin.lib). Las nuevas API solo se agregarán al encabezado combinado (icu.h) y la biblioteca de importación combinada (icu.lib).

Introducción

Hay tres pasos principales a seguir: (Windows 10 Creators Update o superior)

  1. La aplicación debe tener como destino Windows 10 versión 1703 (Creators Update) o superior.

  2. Agregue los encabezados:

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

    En Windows 10 versión 1709 y posteriores, debe incluir el encabezado combinado en su lugar:

    #include <icu.h>
    
  3. Vínculo a las dos bibliotecas:

    • icuuc.lib
    • icuin.lib

    En Windows 10 versión 1903 y posteriores, debe usar la biblioteca combinada en su lugar:

    • icu.lib

A continuación, puede llamar a la API de C de ICU desde estas bibliotecas que desee. (No se expone ninguna API de C++).

Importante

Si usa las bibliotecas de importación heredadas, icuuc.lib e icuin.lib, asegúrese de que se muestran antes de las bibliotecas paraguas, como onecoreuap.lib o WindowsApp.lib, en la configuración del enlazador de dependencias adicionales (consulte la imagen siguiente). De lo contrario, el enlazador se vinculará a icu.lib, lo que dará lugar a un intento de cargar icu.dll durante el tiempo de ejecución. Ese archivo DLL solo está presente a partir de la versión 1903. Por lo tanto, si un usuario actualiza el SDK de Windows 10 en una máquina Windows anterior a la versión 1903, la aplicación no se cargará y ejecutará. Para obtener un historial de las bibliotecas de ICU en Windows, consulte Historial de cambios en la biblioteca de ICU en Windows.

Ejemplo de icu

Nota

  • Esta es la configuración de "Todas las plataformas".
  • Para que las aplicaciones Win32 usen ICU, primero deben llamar a CoInitializeEx . En Windows 10 versión 1903 y posteriores, donde la biblioteca de ICU combinada (icu.dll/icu.lib) está disponible, puede omitir la llamada CoInitializeEx mediante la biblioteca combinada.
  • No todos los datos devueltos por las API de ICU se alinearán con el sistema operativo Windows, ya que este trabajo de alineación sigue en curso. 

Aplicación de ejemplo de ICU

Fragmento de código de ejemplo

A continuación se muestra un ejemplo que ilustra el uso de las API de ICU desde una aplicación para UWP de C++. (No está pensado para ser una aplicación independiente completa, sino simplemente un ejemplo de llamada a un método ICU).

En el ejemplo pequeño siguiente se supone que hay métodos ErrorMessage y OutputMessage que generan las cadenas al usuario de alguna manera.

// 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);
}