유니코드에 대한 국제 구성 요소(ICU)

ICU(International Components for Unicode)는 널리 사용되는 오픈 소스 세계화 API 세트입니다. ICU는 유니코드의 방대한 CLDR(Common Locale Data Repository)을 데이터 라이브러리로 활용하여 소프트웨어 애플리케이션에 대한 세계화 지원을 제공합니다. ICU는 널리 이식 가능하며 모든 플랫폼에서 애플리케이션에 동일한 결과를 제공합니다.

ICU에서 제공하는 세계화 API 서비스의 하이라이트

  • 코드 페이지 변환: 텍스트 데이터를 유니코드와 거의 모든 다른 문자 집합 또는 인코딩으로 변환합니다. ICU의 변환 테이블은 수십 년 동안 IBM에서 수집한 문자 집합 데이터를 기반으로 하며 어디서나 사용할 수 있는 가장 완벽한 테이블입니다.
  • 데이터 정렬: 특정 언어, 지역 또는 국가의 규칙 및 표준에 따라 문자열을 비교합니다. ICU의 데이터 정렬은 CLDR의 유니코드 데이터 정렬 알고리즘과 로캘별 비교 규칙을 기반으로 합니다.
  • 서식 지정: 선택한 로캘의 규칙에 따라 숫자, 날짜, 시간 및 통화 금액의 서식을 지정합니다. 여기에는 월 및 일 이름을 선택한 언어로 번역하고, 적절한 약어를 선택하고, 필드를 올바르게 정렬하는 등이 포함됩니다. 이 데이터는 공통 로캘 데이터 리포지토리에서도 제공됩니다.
  • 시간 계산: 기존의 그레고리오를 넘어 여러 유형의 달력이 제공됩니다. 철저한 표준 시간대 계산 API 집합이 제공됩니다.
  • 유니코드 지원: ICU는 유니코드 표준을 밀접하게 추적하여 유니코드 표준에 지정된 대로 많은 유니코드 문자 속성, 유니코드 정규화, 대/소문자 접기 및 기타 기본 작업에 쉽게 액세스할 수 있습니다.
  • 정규식: ICU의 정규식은 유니코드를 완벽하게 지원하면서 매우 경쟁력 있는 성능을 제공합니다.
  • 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)

위의 두 헤더 파일(icucommon.h 및 icui18n.h)의 내용이 포함된 결합된 헤더 파일 icu.h가 추가되었으며 형식 UCHARchar16_t도 로 변경됩니다.

버전 1903(2019년 5월 업데이트)

"common" 및 "i18n" 라이브러리를 모두 포함하는 새 결합 DLLicu.dll가 추가되었습니다. 또한 새 가져오기 라이브러리가 Windows 10 SDK icu.lib에 추가되었습니다.

앞으로 이전 헤더(icucommon.h 및 icui18n.h) 또는 이전 가져오기 라이브러리(icuuc.lib 및 icuin.lib)에 새 API가 추가되지 않습니다. 새 API는 결합된 헤더(icu.h) 및 결합된 import lib(icu.lib)에만 추가됩니다.

시작하기

따라야 할 세 가지 기본 단계(Windows 10 크리에이터스 업데이트 이상)가 있습니다.

  1. 애플리케이션은 Windows 10 버전 1703(크리에이터 업데이트) 이상을 대상으로 해야 합니다.

  2. 헤더에 를 추가합니다.

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

    Windows 10 버전 1709 이상에서는 결합된 헤더를 대신 포함해야 합니다.

    #include <icu.h>
    
  3. 다음 두 라이브러리에 연결합니다.

    • 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 라이브러리 변경 기록을 참조하세요.

icu 예제

참고

  • 이는 "모든 플랫폼"에 대한 구성입니다.
  • Win32 앱이 ICU를 사용하려면 먼저 CoInitializeEx 를 호출해야 합니다. 결합된 ICU 라이브러리(icu.dll/icu.lib)를 사용할 수 있는 Windows 10 버전 1903 이상에서는 결합된 라이브러리를 사용하여 CoInitializeEx 호출을 생략할 수 있습니다.
  • ICU API에서 반환된 모든 데이터가 Windows OS와 정렬되는 것은 아닙니다. 이 맞춤 작업은 아직 진행 중입니다. 

ICU 예제 앱

예제 코드 조각

다음은 C++ UWP 애플리케이션 내에서 ICU API를 사용하는 방법을 보여 주는 예제입니다. (전체 독립 실행형 애플리케이션이 아니라 ICU 메서드를 호출하는 예제일 뿐입니다.)

다음 작은 예제에서는 문자열을 사용자에게 어떤 방식으로 출력하는 ErrorMessageOutputMessage 메서드가 있다고 가정합니다.

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