2015-11-14 2 views
1

Большинство WinAPI вызовов имеют Unicode и ANSI вызов функцииWinAPI Unicode и ANSI функции

Для examble:

function MessageBoxA(hWnd: HWND; lpText, lpCaption: LPCSTR; uType: UINT): Integer; stdcall;external user32; 

function MessageBoxW(hWnd: HWND; lpText, lpCaption: LPCWSTR; uType: UINT): Integer; stdcall; external user32; 

Когда я должен использовать функцию ANSI вместо вызова функции Unicode?

+2

В 2015 году никогда. –

+0

@JonathanPotter Спасибо. – RepeatUntil

+0

Это небольшое преувеличение. Если вы имеете дело с узкой строкой, закодированной в ASCII, например, потому что вы ее прочитали из сетевого сокета или текстового файла - нет смысла вручную преобразовывать его в UTF-16, чтобы вы могли вызывать MessageBoxW вместо MessageBoxA. (Конечно, вы должны знать, какую кодировку вы используете. Если узкая строка на самом деле находится в UTF-8, вы должны ее преобразовать в UTF-16 и вызвать MessageBoxW.) –

ответ

2

Проще всего следовать этому. Используйте только варианты ANSI для систем, не имеющих варианта Unicode. Это в Windows 95, 98 и ME, которые являются версиями Windows, которые реализуют Win32 и не поддерживают Unicode.

В настоящее время крайне маловероятно, что вы будете ориентироваться на такие версии, и поэтому, по всей вероятности, вы всегда должны использовать варианты Unicode.

+2

Следует отметить, что Win9x на самом деле был очень ограниченным поддержка Unicode (https://support.microsoft.com/en-us/kb/210341). Кроме того, был выпущен «Microsoft Layer для Unicode в Windows 95/98/ME» (https://msdn.microsoft.com/en-us/goglobal/bb688166.aspx), который несколько расширил эту поддержку. – dxiv

4

Подобно тому, как (редкие) исключения посланных комментариев/ответы ...

Можно выбрать использовать ANSI звонков в тех случаях, когда UTF-8, как ожидается, и поддерживается. Например, WriteConsoleA'ing строки UTF-8 в консоли, установленной для использования шрифта TT и работающего под chcp 65001.

Еще одним исключением является функция, которая в основном реализована как ANSI, где вариант Unicode «W» просто преобразуется в узкую строку в активной кодовой странице и вызывает аналог «A». Для такой функции, и когда доступна узкая строка, вызов варианта «А» напрямую сохраняет избыточное двойное преобразование. Дело в том, что это OutputDebugString, который попал в эту категорию до Windows 10 (я только заметил https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362.aspx, в котором упоминается, что вызов WaitForDebugEventEx - доступный только с Windows 10 - включает в себя истинный выход Unicode для OutputDebugStringW).

Тогда есть API, которые, хотя и имеют дело со строками, являются ANSI. Например, GetProcAddress существует только в варианте ANSI, который принимает аргумент LPCSTR, поскольку имена в таблицах экспорта являются узкими строками.

Это говорит о том, что большинство API-интерфейсов, основанных на строках, являются в основном Unicode, и рекомендуется использовать варианты «W». Не все новые API даже имеют вариант «А» больше (например, CommandLineToArgvW). Из уст лошадей https://msdn.microsoft.com/en-us/library/windows/desktop/ff381407.aspx:

Windows изначально поддерживает строки Unicode для элементов пользовательского интерфейса, имена файлов и т. Д. Unicode является предпочтительным кодированием символов, поскольку он поддерживает все наборы символов и языки. Windows представляет символы Unicode, используя кодировку UTF-16, в которой каждый символ кодируется как 16-битное значение. Символы UTF-16 называются широкими символами, чтобы отличать их от 8-разрядных символов ANSI.

[...] Когда Microsoft была введена поддержка Unicode в Windows, она облегчила переход, предоставляя два параллельных набор API-интерфейсов, один для строк ANSI, а другие для строк Unicode.

[...] Внутренне версия ANSI переводит строку в Unicode. Заголовки Windows также определяют макрос, который разрешает версию Unicode, когда обозначен символ препроцессора UNICODE или версия ANSI.

[...] Большинство новых API, в Windows, есть только версии Unicode, без соответствующего ANSI-версии.

[Примечание]  Сообщение было отредактировано, чтобы добавить два последних абзаца.

+0

Это на самом деле лучший ответ, чем принятый ответ. Хотя оба ответа верны, этот вопрос лучше решает вопрос. Возможно, вы захотите добавить, что все поддерживаемые версии Windows (то есть системы на базе Windows NT) используют UTF-16LE внутри и конвертируют из/в кодировку ANSI при использовании ANSI-версий вызовов API. Таким образом, ваш ответ является самодостаточным и остается полезным, даже когда другие ответы/комментарии удаляются. – IInspectable

+0

@Intpectable мое намерение было указать некоторые исключения, поскольку правило было довольно очевидным. Но вы правы, и я только что отредактировал свой ответ на этот вопрос. – dxiv

+0

@ Отличное спасибо за редактирование. CommandLineToArgvW - хороший пример API W-only, и на самом деле он восходит по крайней мере к NT 3.51. – dxiv

Смежные вопросы