ICU (International Components for Unicode)

International Components for Unicode (ICU) est un ensemble mature et largement utilisé d’API de globalisation open source. L’ICU utilise le vaste référentiel CLDR (Common Locale Data Repository) d’Unicode comme bibliothèque de données, fournissant une prise en charge de la globalisation pour les applications logicielles. L’ICU est largement portable et donne aux applications les mêmes résultats sur toutes les plateformes.

Faits saillants des services d’API globalisation fournis par l’ICU

  • Conversion de page de codes : convertissez des données de texte vers ou à partir d’Unicode et presque n’importe quel autre jeu de caractères ou encodage. Les tables de conversion d’ICU sont basées sur des données de jeu de caractères collectées par IBM au cours de nombreuses décennies, et sont les plus complètes disponibles partout.
  • Classement : comparez les chaînes en fonction des conventions et normes d’une langue, d’une région ou d’un pays particulier. Le classement de l’ICU est basé sur l’algorithme de classement Unicode et les règles de comparaison spécifiques aux paramètres régionaux du CLDR.
  • Mise en forme : Mettez en forme les nombres, les dates, les heures et les montants monétaires selon les conventions d’un paramètre régional choisi. Cela inclut la traduction des noms de mois et de jours dans la langue sélectionnée, le choix des abréviations appropriées, le classement correct des champs, etc. Ces données proviennent également du référentiel common locale data.
  • Calculs temporels : plusieurs types de calendriers sont fournis au-delà du grégorien traditionnel. Un ensemble complet d’API de calcul de fuseau horaire est fourni.
  • Prise en charge d’Unicode : ICU suit étroitement la norme Unicode, ce qui permet d’accéder facilement à toutes les nombreuses propriétés de caractères Unicode, à la normalisation Unicode, au pliage de cas et à d’autres opérations fondamentales spécifiées par la norme Unicode.
  • Expression régulière : les expressions régulières de l’ICU prennent entièrement en charge Unicode tout en offrant des performances très compétitives.
  • Bidi : prise en charge de la gestion de texte contenant un mélange de données de gauche à droite (anglais) et de droite à gauche (arabe ou hébreu).

Pour plus d’informations, vous pouvez visiter le site web de l’ICU : http://site.icu-project.org/

Vue d’ensemble

Dans Windows 10 Creators Update, iCU a été intégré à Windows, rendant les API C et les données accessibles publiquement.

Important

La version d’ICU dans Windows expose uniquement les API C. Il n’expose aucune des API C++. Malheureusement, il est impossible d’exposer les API C++ en raison de l’absence d’un ABI stable en C++.

Pour obtenir de la documentation sur les API C de l’ICU, reportez-vous à la page officielle de documentation ICU ici : http://icu-project.org/apiref/icu4c/index.html#Module

Historique des modifications apportées à la bibliothèque ICU dans Windows

Version 1703 (Creators Update)

La bibliothèque ICU a été ajoutée pour la première fois au système d’exploitation Windows 10 dans cette version. Il a été ajouté en tant que :

  • Deux DLL système :
    • icuuc.dll (il s’agit de la bibliothèque « commune » de l’ICU)
    • icuin.dll (il s’agit de la bibliothèque ICU « i18n »)
  • Deux fichiers d’en-tête dans le SDK Windows 10 :
    • icucommon.h
    • icui18n.h
  • Deux bibliothèques d’importation dans le Kit de développement logiciel (SDK) Windows 10 :
    • icuuc.lib
    • icuin.lib

Version 1709 (Fall Creators Update)

Un fichier d’en-tête combiné, icu.h, a été ajouté, qui contient le contenu des deux fichiers d’en-tête ci-dessus (icucommon.h et icui18n.h), et modifie également le type de UCHAR en char16_t.

Version 1903 (mise à jour de mai 2019)

Une nouvelle DLL combinée, icu.dll, a été ajoutée, qui contient les bibliothèques « common » et « i18n ». En outre, une nouvelle bibliothèque d’importation a été ajoutée au Kit de développement logiciel (SDK) Windows 10 : icu.lib.

À l’avenir, aucune nouvelle API ne sera ajoutée aux anciens en-têtes (icucommon.h et icui18n.h) ou aux anciennes bibliothèques d’importation (icuuc.lib et icuin.lib). Les nouvelles API seront ajoutées uniquement à l’en-tête combiné (icu.h) et à la bibliothèque d’importation combinée (icu.lib).

Mise en route

Il existe trois étapes main à suivre : (Windows 10 Creators Update ou supérieur)

  1. Votre application doit cibler Windows 10 version 1703 (Creators Update) ou ultérieure.

  2. Ajoutez dans les en-têtes :

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

    Sur Windows 10 version 1709 et ultérieures, vous devez inclure l’en-tête combiné à la place :

    #include <icu.h>
    
  3. Lien vers les deux bibliothèques :

    • icuuc.lib
    • icuin.lib

    Sur Windows 10 version 1903 et ultérieures, vous devez utiliser la bibliothèque combinée à la place :

    • icu.lib

Ensuite, vous pouvez appeler l’API C de l’ICU à partir de ces bibliothèques de votre choix. (Aucune API C++ n’est exposée.)

Important

Si vous utilisez les bibliothèques d’importation héritées, icuuc.lib et icuin.lib, assurez-vous qu’elles sont répertoriées avant les bibliothèques parapluies, comme onecoreuap.lib ou WindowsApp.lib, dans le paramètre Éditeur de liens dépendances supplémentaires (voir l’image ci-dessous). Sinon, l’éditeur de liens est lié à icu.lib, ce qui entraîne une tentative de chargement icu.dll au moment de l’exécution. Cette DLL est présente uniquement à partir de la version 1903. Par conséquent, si un utilisateur met à niveau le Kit de développement logiciel (SDK) Windows 10 sur une machine Windows préversion 1903, le chargement et l’exécution de l’application échouent. Pour obtenir un historique des bibliothèques d’ICU dans Windows, consultez Historique des modifications apportées à la bibliothèque d’ICU dans Windows.

Exemple icu

Notes

  • Il s’agit de la configuration pour « Toutes les plateformes ».
  • Pour que les applications Win32 utilisent l’ICU, elles doivent d’abord appeler CoInitializeEx . Sur Windows 10 version 1903 et ultérieure, où la bibliothèque d’ICU combinée (icu.dll/icu.lib) est disponible, vous pouvez omettre l’appel CoInitializeEx à l’aide de la bibliothèque combinée.
  • Toutes les données retournées par les API ICU ne s’alignent pas sur le système d’exploitation Windows, car ce travail d’alignement est toujours en cours. 

Exemple d’application ICU

Exemple d’extrait de code

Voici un exemple illustrant l’utilisation des API ICU à partir d’une application UWP C++. (Il n’est pas destiné à être une application autonome complète, mais simplement un exemple d’appel d’une méthode ICU.)

Le petit exemple suivant suppose qu’il existe des méthodes ErrorMessage et OutputMessage qui affichent les chaînes à l’utilisateur d’une manière ou d’une autre.

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