Функция MultiByteToWideChar (stringapiset.h)

Сопоставляет символьную строку со строкой UTF-16 (расширенный символ). Символьная строка не обязательно из многобайтовой кодировки.

Осторожностью Неправильное использование функции MultiByteToWideChar может поставить под угрозу безопасность приложения. Вызов этой функции может легко вызвать переполнение буфера, так как размер входного буфера, указанного lpMultiByteStr , равен количеству байтов в строке, а размер выходного буфера, указанного lpWideCharStr , равен количеству символов. Чтобы избежать переполнения буфера, приложение должно указать размер буфера, соответствующий типу данных, который получает буфер. Дополнительные сведения см. в разделе Вопросы безопасности: международные функции.
 
Примечание Кодовые страницы ANSI могут быть разными на разных компьютерах или изменяться для одного компьютера, что приводит к повреждению данных. Для получения наиболее согласованных результатов приложения должны использовать Юникод, например UTF-8 или UTF-16, вместо определенной кодовой страницы, если только устаревшие стандарты или форматы данных не препятствуют использованию Юникода. Если использование Юникода невозможно, приложения должны помечать поток данных соответствующим именем кодирования, если это разрешено протоколами. HTML и XML-файлы разрешают добавление тегов, а текстовые файлы — нет.
 

Синтаксис

int MultiByteToWideChar(
  [in]            UINT                              CodePage,
  [in]            DWORD                             dwFlags,
  [in]            _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr,
  [in]            int                               cbMultiByte,
  [out, optional] LPWSTR                            lpWideCharStr,
  [in]            int                               cchWideChar
);

Параметры

[in] CodePage

Кодовая страница, используемая при преобразовании. Для этого параметра можно задать значение любой кодовой страницы, установленной или доступной в операционной системе. Список кодовых страниц см. в разделе Кодовые страницы Идентификаторы. Приложение также может указать одно из значений, показанных в следующей таблице.

Значение Значение
CP_ACP
Системная кодовая страница Windows ANSI по умолчанию.
Примечание Это значение может отличаться на разных компьютерах, даже в одной сети. Его можно изменить на том же компьютере, что приведет к непоправимому повреждению хранимых данных. Это значение предназначено только для временного использования, а постоянное хранилище должно использовать UTF-16 или UTF-8, если это возможно.
 
CP_MACCP
Текущая системная кодовая страница Macintosh.
Примечание Это значение может отличаться на разных компьютерах, даже в одной сети. Его можно изменить на том же компьютере, что приведет к непоправимому повреждению хранимых данных. Это значение предназначено только для временного использования, а постоянное хранилище должно использовать UTF-16 или UTF-8, если это возможно.
 
Примечание Это значение используется в основном в устаревшем коде и, как правило, не требуется, так как современные компьютеры Macintosh используют Юникод для кодирования.
 
CP_OEMCP
Текущая страница кода изготовителя оборудования системы.
Примечание Это значение может отличаться на разных компьютерах, даже в одной сети. Его можно изменить на том же компьютере, что приведет к непоправимому повреждению хранимых данных. Это значение предназначено только для временного использования, а постоянное хранилище должно использовать UTF-16 или UTF-8, если это возможно.
 
CP_SYMBOL
Кодовая страница символов (42).
CP_THREAD_ACP
Кодовая страница Windows ANSI для текущего потока.
Примечание Это значение может отличаться на разных компьютерах, даже в одной сети. Его можно изменить на том же компьютере, что приведет к непоправимому повреждению хранимых данных. Это значение предназначено только для временного использования, а постоянное хранилище должно использовать UTF-16 или UTF-8, если это возможно.
 
CP_UTF7
UTF-7. Используйте это значение только при принудительном использовании 7-разрядного транспортного механизма. Рекомендуется использовать UTF-8.
CP_UTF8
UTF-8.

[in] dwFlags

Флаги, указывающие тип преобразования. Приложение может указать сочетание следующих значений, при этом по умолчанию используется MB_PRECOMPOSED. MB_PRECOMPOSED и MB_COMPOSITE являются взаимоисключающими. MB_USEGLYPHCHARS и MB_ERR_INVALID_CHARS можно задать независимо от состояния других флагов.

Значение Значение
MB_COMPOSITE Всегда используйте разложенные символы, т. е. символы, в которых базовый символ и один или несколько символов без знака имеют уникальные значения кодовых точек. Например, Ä представлена A + ированием: ЛАТИНСКАЯ ПРОПИСНАЯ БУКВа A (U+0041) + COMBINING DIAERESIS (U+0308). Обратите внимание, что этот флаг нельзя использовать с MB_PRECOMPOSED.
MB_ERR_INVALID_CHARS Сбой при обнаружении недопустимого входного символа.

Начиная с Windows Vista функция не удаляет недопустимые кодовые точки, если приложение не устанавливает этот флаг, а заменяет недопустимые последовательности на U+FFFD (закодированные в соответствии с указанной кодовой страницой).

Windows 2000 с пакетом обновления 4 (SP4) и более поздние версии, Windows XP: Если этот флаг не установлен, функция автоматически удаляет недопустимые кодовые точки. Вызов GetLastError возвращает ERROR_NO_UNICODE_TRANSLATION.
MB_PRECOMPOSED
По умолчанию; не использовать с MB_COMPOSITE. Всегда используйте предварительно композированные символы, т. е. символы, имеющие однозначное значение для базовой или несмеченной комбинации символов. Например, в символе è e является базовым символом, а знак подчеркивания — символом nonspacing. Если для символа определена одна кодовая точка Юникода, приложение должно использовать ее вместо отдельных базовых и ненаправленных символов. Например, Ä представлен одной кодовой точкой Юникода LATIN CAPITAL LETTER A WITH DIAERESIS (U+00C4).
MB_USEGLYPHCHARS
Используйте символы глифа вместо контрольных символов.

Для кодовых страниц, перечисленных ниже, dwFlags должно иметь значение 0. В противном случае функция завершается сбоем с ERROR_INVALID_FLAGS.

  • 50220
  • 50221
  • 50222
  • 50225
  • 50227
  • 50229
  • От 57002 до 57011
  • 65000 (UTF-7)
  • 42 (символ)

Примечание

 Для UTF-8 или кодовой страницы 54936 (GB18030, начиная с Windows Vista) для dwFlags необходимо задать значение 0 или MB_ERR_INVALID_CHARS. В противном случае функция завершается сбоем с ERROR_INVALID_FLAGS.

[in] lpMultiByteStr

Указатель на преобразуемую символьную строку.

[in] cbMultiByte

Размер (в байтах) строки, указанной параметром lpMultiByteStr . Кроме того, этот параметр может иметь значение -1, если строка заканчивается null. Обратите внимание, что если cbMultiByte имеет значение , функция завершается 0ошибкой.

Если этот параметр равен -1, функция обрабатывает всю входную строку, включая завершающий символ NULL. Таким образом, результирующая строка Юникода имеет завершающий символ NULL, а длина, возвращаемая функцией, включает этот символ.

Если для этого параметра задано положительное целое число, функция обрабатывает точно указанное число байтов. Если указанный размер не содержит завершающий символ NULL, результирующая строка Юникода не завершается null, а возвращаемая длина не включает этот символ.

[out, optional] lpWideCharStr

Указатель на буфер, который получает преобразованную строку.

[in] cchWideChar

Размер буфера в символах, указанный lpWideCharStr. Если это значение равно 0, функция возвращает требуемый размер буфера в символах, включая любой завершающий пустой символ, и не использует буфер lpWideCharStr .

Возвращаемое значение

Возвращает количество символов, записанных в буфер, указанный lpWideCharStr в случае успешного выполнения. Если функция выполнена успешно и cchWideChar имеет значение 0, возвращаемое значение — это требуемый размер в символах для буфера, указанного lpWideCharStr. Сведения о том, как флаг MB_ERR_INVALID_CHARS влияет на возвращаемое значение при входе недопустимых последовательностей, см. также в разделе dwFlags.

Функция возвращает значение 0 , если она не выполнена успешно. Чтобы получить расширенные сведения об ошибке, приложение может вызвать Метод GetLastError, который может возвращать один из следующих кодов ошибок:

  • ERROR_INSUFFICIENT_BUFFER: указанный размер буфера не был достаточно велик или для него неправильно задано значение NULL.
  • ERROR_INVALID_FLAGS. Значения, указанные для флагов, были недопустимыми.
  • ERROR_INVALID_PARAMETER: любое из значений параметров было недопустимым.
  • ERROR_NO_UNICODE_TRANSLATION: в строке обнаружен недопустимый Юникод.

Комментарии

По умолчанию эта функция преобразуется в предварительно компилированную форму входной символьной строки. Если предкомпозитная форма не существует, функция пытается преобразовать в составную форму.

Использование флага MB_PRECOMPOSED очень мало влияет на большинство кодовых страниц, так как большинство входных данных уже составлены. Попробуйте вызвать NormalizeString после преобразования с помощью MultiByteToWideChar. NormalizeString предоставляет более точные, стандартные и согласованные данные, а также может выполняться быстрее. Обратите внимание, что для перечисления NORM_FORM , передаваемого в NormalizeString, NormalizationC соответствует MB_PRECOMPOSED, а NormalizationD — MB_COMPOSITE.

Как упоминалось в приведенном выше предостережении, выходной буфер можно легко перезагрузить, если эта функция не вызывается с параметром cchWideChar для 0 получения требуемого размера. Если используется флаг MB_COMPOSITE, выходные данные могут содержать три или более символов для каждого входного символа.

Указатели lpMultiByteStr и lpWideCharStr не должны совпадать. Если они совпадают, функция завершается сбоем, и GetLastError возвращает значение ERROR_INVALID_PARAMETER.

MultiByteToWideChar не завершает выходную строку со значением NULL, если длина входной строки явно указана без завершающего символа NULL. Чтобы завершить выходную строку для этой функции со значением NULL, приложение должно передать значение -1 или явно подсчитать завершающий символ NULL для входной строки.

Функция завершается ошибкой, если задано MB_ERR_INVALID_CHARS и в исходной строке обнаружен недопустимый символ. Недопустимым символом является один из следующих:

  • Символ, который не является символом по умолчанию в исходной строке, но преобразуется в символ по умолчанию, если MB_ERR_INVALID_CHARS не задан.
  • Для строк DBCS — символ, имеющий байт в начале, но не имеющий допустимого байта.

Начиная с Windows Vista эта функция полностью соответствует спецификации Юникода 4.1 для UTF-8 и UTF-16. Функция, используемая в более ранних операционных системах, кодирует или декодирует одинокие суррогатные половинки или несовпадение суррогатных пар. Код, написанный в более ранних версиях Windows, который использует это поведение для кодирования случайных нетекстовых двоичных данных, может столкнуться с проблемами. Однако код, использующий эту функцию в допустимых строках UTF-8, будет вести себя так же, как и в более ранних операционных системах Windows.

Windows XP: Чтобы предотвратить проблему безопасности, связанную с некратчайшие версии символов UTF-8, MultiByteToWideChar удаляет эти символы.

Начиная с Windows 8:MultiByteToWideChar объявляется в Stringapiset.h. До Windows 8 он был объявлен в Winnls.h.

Пример кода

catch (std::exception e)
{
    // Save in-memory logging buffer to a log file on error.

    ::std::wstring wideWhat;
    if (e.what() != nullptr)
    {
        int convertResult = MultiByteToWideChar(CP_UTF8, 0, e.what(), (int)strlen(e.what()), NULL, 0);
        if (convertResult <= 0)
        {
            wideWhat = L"Exception occurred: Failure to convert its message text using MultiByteToWideChar: convertResult=";
            wideWhat += convertResult.ToString()->Data();
            wideWhat += L"  GetLastError()=";
            wideWhat += GetLastError().ToString()->Data();
        }
        else
        {
            wideWhat.resize(convertResult + 10);
            convertResult = MultiByteToWideChar(CP_UTF8, 0, e.what(), (int)strlen(e.what()), &wideWhat[0], (int)wideWhat.size());
            if (convertResult <= 0)
            {
                wideWhat = L"Exception occurred: Failure to convert its message text using MultiByteToWideChar: convertResult=";
                wideWhat += convertResult.ToString()->Data();
                wideWhat += L"  GetLastError()=";
                wideWhat += GetLastError().ToString()->Data();
            }
            else
            {
                wideWhat.insert(0, L"Exception occurred: ");
            }
        }
    }
    else
    {
        wideWhat = L"Exception occurred: Unknown.";
    }

    Platform::String^ errorMessage = ref new Platform::String(wideWhat.c_str());
    // The session added the channel at level Warning. Log the message at
    // level Error which is above (more critical than) Warning, which
    // means it will actually get logged.
    _channel->LogMessage(errorMessage, LoggingLevel::Error);
    SaveLogInMemoryToFileAsync().then([=](StorageFile^ logFile) {
        _logFileGeneratedCount++;
        StatusChanged(this, ref new LoggingScenarioEventArgs(LoggingScenarioEventType::LogFileGenerated, logFile->Path->Data()));
    }).wait();
}

Пример из универсальных примеров Windows на сайте GitHub.

Требования

Требование Значение
Минимальная версия клиента Windows 2000 Профессиональная [классические приложения | Приложения UWP]
Минимальная версия сервера Windows 2000 Server [классические приложения | Приложения UWP]
Целевая платформа Windows
Header stringapiset.h (включая Windows.h)
Библиотека Kernel32.lib
DLL Kernel32.dll

См. также

Функции Юникода и кодировки

Юникод и наборы символов

WideCharToMultiByte

API-интерфейсы Vertdll, доступные в анклавах VBS