понедельник, 3 мая 2010 г.

Маленькая особенность OutputDebugString

   Начиная с Windows 2000, все операционные системы Microsoft линейки NT целиком и полностью построены на Unicode. Все ключевые функции для создания окон, вывода текста, операций со строками и т.д. требуют Unicode-строк. Если какой-то функции Windows передается ANSI-строка, она сначала преобразуется в Unicode и лишь потом передается операционной системе.
   В реализации это выглядит так: для функции доступной через API может существовать две версии: Ansi (принимает строки ANSI) и Wide (принимает строки Unicode) - например CreateProcessA и CreateProcessW. И Ansi-версия является оболочкой (шлюзом) к Wide.

   Но оказывается есть и исключения...

   Таким исключением является функция OutputDebugString. Для нее Wide-версия - это оболочка над Ansi. И при вызове OutputDebugStringW переданная строка преобразуется в ANSI-строку и передается OutputDebugStringA.

   Псевдокод OutputDebugStringW (Delphi)
procedure OutputDebugStringW(const lpOutputString: PWideChar); stdcall;
var
  UnicodeString: UNICODE_STRING;
  AnsiString: ANSI_STRING;
  Status: NTSTATUS;
begin
  RtlInitUnicodeString(@UnicodeString, lpOutputString);
  Status := RtlUnicodeStringToAnsiString(@AnsiString, @UnicodeString, True);
  if not NT_SUCCESS(Status) then
    AnsiString.Buffer := '';
  OutputDebugStringA(AnsiString.Buffer);
  if NT_SUCCESS(Status) then
    RtlFreeAnsiString(@AnsiString);
end;
   Так что, если есть желание избежать лишней траты времени и денег памяти, при использовании OutputDebugString лучше напрямую использовать Ansi-версию :)

Ссылки
[1] Understanding Win32 "OutputDebugString"

Комментариев нет:

Отправить комментарий