stringtranslate.com

Юникод в Microsoft Windows

Microsoft была одной из первых компаний, реализовавших Unicode в своих продуктах. Windows NT была первой операционной системой, которая использовала «широкие символы» в системных вызовах . Сначала использовалась (ныне устаревшая) схема кодирования UCS-2 , но начиная с Windows 2000 она была обновлена ​​до кодировки переменной ширины UTF-16 , что позволило представлять дополнительные плоскости с помощью суррогатных пар. Однако Microsoft не поддерживала UTF-8 в своем API до мая 2019 года.

До 2019 года Microsoft делала упор на UTF-16 (т. е. API -W), но с тех пор рекомендовала использовать UTF-8 (по крайней мере, в некоторых случаях) [1] в Windows и Xbox (и в других своих продуктах), даже заявляя, что «UTF-8 — это универсальная кодовая страница для интернационализации, [и] UTF-16 [...] является уникальной нагрузкой, которую Windows возлагает на код, предназначенный для нескольких платформ. [..] Windows [движется] вперед к поддержке UTF-8, чтобы устранить эту уникальную нагрузку, [что приведет] к меньшему количеству проблем с интернационализацией в приложениях и играх». [2]

В большом количестве документации Microsoft слово «Unicode» используется для явного указания на кодировку UTF-16. Все остальное, включая UTF-8, не является «Unicode» в устаревшем языке Microsoft (в то время как UTF-8 и UTF-16 являются Unicode согласно стандарту Unicode или его кодировкам/«форматам преобразования»).

В различных семействах Windows

Системы на базе Windows NT

Текущие версии Windows и все версии вплоть до Windows XP и более ранних Windows NT (3.x, 4.0) поставляются с системными библиотеками , которые поддерживают кодировку строк двух типов: 16-битную «Unicode» ( UTF-16 начиная с Windows 2000 ) и (иногда многобайтовую) кодировку, называемую « кодовой страницей » (или неправильно называемую кодовой страницей ANSI ). 16-битные функции имеют имена с суффиксом «W» (от «wide» ), например SetWindowTextW. Функции, ориентированные на кодовую страницу, используют суффикс «A» для «ANSI», например SetWindowTextA(некоторые другие соглашения использовались для API, скопированных из других систем, например _wfopen/fopenили wcslen/strlen). Такое разделение было необходимо, поскольку многие языки, включая C , не предоставляли понятного способа передачи как 8-битных, так и 16-битных строк в одну и ту же функцию.

Microsoft попыталась обеспечить «переносимую» поддержку Unicode, предоставив компилятору переключатель «UNICODE», который переключает несуффиксные «универсальные» вызовы с интерфейса «A» на интерфейс «W» и преобразует все строковые константы в «широкие» версии UTF-16. [3] [4] На самом деле это не работает, поскольку не преобразует UTF-8 за пределы строковых констант, в результате чего код, который пытается открыть файлы, просто не компилируется. [ необходима цитата ]

Ранее и независимо от переключателя «UNICODE» Windows также предоставляла переключатель API многобайтовых наборов символов (MBCS). [5] Это изменяет некоторые функции, которые не работают в MBCS, например, strrevна поддерживающие MBCS, такие как _mbsrev. [6] [7]

Windows CE

В (ныне прекращенной) Windows CE UTF-16 использовался почти исключительно, а API «A» в основном отсутствовал. [8] Ограниченный набор API ANSI доступен в Windows CE 5.0 для использования в сокращенном наборе локалей, которые могут быть выборочно встроены в образ среды выполнения. [9]

Windows 9x

В 2001 году Microsoft выпустила специальное дополнение к старым системам Microsoft Windows 9x . Оно включает в себя динамическую библиотеку 'unicows.dll' (всего 240 КБ), содержащую 16-битную версию (те, что с буквой W на конце) всех основных функций Windows API. Это всего лишь слой трансляции: SetWindowTextWон просто преобразует свои входные данные, используя текущую кодовую страницу, и вызывает SetWindowTextA.

UTF-8

Microsoft Windows ( Windows XP и более поздние версии) имеет кодовую страницу, предназначенную для UTF-8 , кодовую страницу 65001 [10] или CP_UTF8. Долгое время было невозможно установить кодовую страницу локали на 65001, оставляя эту кодовую страницу доступной только для a) явных функций преобразования, таких как MultiByteToWideChar и/или b) консольной команды Win32chcp 65001 для перевода stdin/out между UTF-8 и UTF-16. Это означало, что «узкие» функции, в частности fopen(которые открывают файлы), не могли быть вызваны со строками UTF-8, и фактически не было способа открыть все возможные файлы, fopenнезависимо от того, какая была установлена ​​локаль и/или какие байты были помещены в строку, поскольку ни одна из доступных локалей не могла выдать все возможные символы UTF-16. Эта проблема также касалась всех других API, которые принимают или возвращают 8-битные строки, включая Windows, такие как SetWindowText.

Программы, которые хотели использовать UTF-8, в частности код, предназначенный для переноса на другие операционные системы, нуждались в обходном пути для этого недостатка. Обычным обходным путем было добавление новых функций для открытия файлов, которые преобразуют UTF-8 в UTF-16 с помощью MultiByteToWideChar и вызывают функцию «wide» вместо fopen. [11] Десятки многоплатформенных библиотек добавили функции-оболочки для выполнения этого преобразования в Windows (и пропускания UTF-8 без изменений на других платформах), примером является предлагаемое дополнение к Boost , Boost.Nowide . [12] Другим популярным обходным путем было преобразование имени в эквивалент имени файла 8.3 , это необходимо, если fopenнаходится внутри библиотеки. Ни один из этих обходных путей не считается хорошим, так как они требуют изменений в коде, который работает не на Windows.

В апреле 2018 г. (или, возможно, в ноябре 2017 г. [13] ) с инсайдерской сборкой 17035 (номинальной сборкой 17134) для Windows 10 появился флажок «Бета: использовать Unicode UTF-8 для поддержки языков во всем мире» для установки кодовой страницы локали на UTF-8. [a] Это позволяет вызывать «узкие» функции, включая fopenи SetWindowTextA, со строками UTF-8. Однако это общесистемная настройка, и программа не может предполагать, что она установлена.

В мае 2019 года компания Microsoft добавила возможность для программы самостоятельно устанавливать кодовую страницу UTF-8 [1] [14], что позволило неопытным пользователям запускать программы, написанные для использования UTF-8.

Начиная с 2019 года Microsoft рекомендует программистам использовать UTF-8 (например, вместо любой другой 8-битной кодировки) [1] в Windows и Xbox и, возможно, рекомендует использовать его вместо UTF-16, даже заявляя, что «UTF-8 — это универсальная кодовая страница для интернационализации [и] UTF-16 [..] — это уникальная нагрузка, которую Windows возлагает на код, предназначенный для нескольких платформ». [2] Microsoft, похоже, переходит на UTF-8, заявляя, что ранее подчеркивала свою альтернативу, а в Windows 11 некоторые системные файлы обязаны использовать UTF-8 и не требуют метки порядка байтов. [15] Блокнот теперь может распознавать UTF-8 без метки порядка байтов и может быть настроен на запись UTF-8 без метки порядка байтов. [ требуется цитата ] Некоторые другие продукты Microsoft используют UTF-8 внутри себя, включая Visual Studio [ требуется цитата ] и SQL Server 2019 , при этом Microsoft заявляет о 35%-ном увеличении скорости за счет использования UTF-8 и «почти 50%-ном снижении требований к хранилищу». [16]

Компиляторы

До 2019 года компиляторы Microsoft не могли создавать строковые константы UTF-8 из исходных файлов UTF-8. Это было связано с тем, что они преобразовывали все строки в кодовую страницу локали (которая не могла быть UTF-8). Одно время единственным способом обойти это было отключение UNICODE и не помечать входной файл как UTF-8 (т. е. не использовать BOM ). [17] Это заставило бы компилятор думать, что и входные, и выходные данные находятся в одной и той же однобайтовой локали, и оставило бы строки нетронутыми. В современных системах помогает установка кодовой страницы на UTF-8. [ требуется цитата ]

Смотрите также

Примечания

  1. ^ Находится в панели управления, пункт «Регион», вкладка «Администрирование», кнопка «Изменить региональные параметры системы».

Ссылки

  1. ^ abc "Использование кодовых страниц UTF-8 в приложениях Windows". learn.microsoft.com . Получено 2020-06-06 . Начиная с версии Windows 1903 (обновление за май 2019 г.), вы можете использовать свойство ActiveCodePage в appxmanifest для упакованных приложений или манифест fusion для неупакованных приложений, чтобы заставить процесс использовать UTF-8 в качестве кодовой страницы процесса. [...] CP_ACPэквивалентно CP_UTF8только если запущено в Windows версии 1903 (обновление за май 2019 г.) или выше, а свойство ActiveCodePage, описанное выше, установлено в UTF-8. В противном случае он учитывает устаревшую системную кодовую страницу. Мы рекомендуем использовать CP_UTF8явно.
  2. ^ ab "Поддержка UTF-8 в Microsoft Game Development Kit (GDK) - Microsoft Game Development Kit". learn.microsoft.com . 19 августа 2022 г. . Получено 2023-03-05 . Работая в UTF-8, вы можете обеспечить максимальную совместимость [..] Windows изначально работает в UTF-16 (или WCHAR), что требует преобразования кодовых страниц с помощью MultiByteToWideChar и WideCharToMultiByte. Это уникальная нагрузка, которую Windows возлагает на код, предназначенный для нескольких платформ. [..] Microsoft Game Development Kit (GDK) и Windows в целом продвигаются вперед к поддержке UTF-8, чтобы снять эту уникальную нагрузку Windows на целевое использование кода или его обмен с несколькими платформами и Интернетом. Кроме того, это приводит к меньшему количеству проблем с интернационализацией в приложениях и играх и сокращает тестовую матрицу, необходимую для правильной работы.
  3. ^ "Unicode в Windows API" . Получено 7 мая 2018 г. .
  4. ^ "Соглашения для прототипов функций (Windows)". MSDN . Получено 7 мая 2018 г. .
  5. ^ "Поддержка многобайтовых наборов символов (MBCS)" . Получено 2020-06-15 .
  6. ^ "Двухбайтовые наборы символов". MSDN . 2018-05-31 . Получено 2020-06-15 . наши приложения используют кодовые страницы Windows DBCS с версиями "A" функций Windows.
  7. ^ _strrev, _wcsrev, _mbsrev, _mbsrev_l Документация Microsoft
  8. ^ "Различия между реализациями TAPI в Windows CE и Windows NT". MSDN . 28 августа 2006 г. Получено 7 мая 2018 г. Windows CE основана на Unicode. Возможно, вам придется перекомпилировать исходный код, написанный для приложения на базе Windows NT.
  9. ^ "Кодовые страницы (Windows CE 5.0)". Microsoft Docs . 14 сентября 2012 г. Получено 7 мая 2018 г.
  10. ^ «Идентификаторы кодовых страниц (Windows)». msdn.microsoft.com . 7 января 2021 г.
  11. ^ "UTF-8 в Windows". Stack Overflow . Получено 1 июля 2011 г.
  12. ^ "Boost.Nowide". GitHub .
  13. ^ "Windows10 Insider Preview Build 17035 поддерживает UTF-8 как ANSI". Hacker News . Получено 7 мая 2018 г. .
  14. ^ «Windows 10 1903 и более поздние версии наконец-то поддерживают UTF-8 с формами A функций Win32».
  15. ^ "Настройка меню "Пуск" в Windows 11". docs.microsoft.com . Получено 2021-06-29 . Убедитесь, что ваш LayoutModification.json использует кодировку UTF-8.
  16. ^ "Введение в поддержку UTF-8 для SQL Server". techcommunity.microsoft.com . 2019-07-02 . Получено 2021-08-24 . Например, изменение существующего типа данных столбца с NCHAR(10) на CHAR(10) с использованием сортировки с поддержкой UTF-8 приводит к почти 50%-ному сокращению требований к хранилищу. [..] В диапазоне ASCII при выполнении интенсивного ввода-вывода чтения/записи в UTF-8 мы измерили среднее улучшение производительности на 35% по сравнению с UTF-16 с использованием кластеризованных таблиц с некластеризованным индексом по строковому столбцу и среднее улучшение производительности на 11% по сравнению с UTF-16 с использованием кучи.
  17. ^ Часто задаваемые вопросы о UTF-8 Everywhere: как записать строковый литерал UTF-8 в коде C++?

Внешние ссылки