Подтвердить что ты не робот

Почему PDWord не DWORD?

Эта программа

{$APPTYPE CONSOLE}
{$TYPEDADDRESS ON}

uses
  Winapi.Windows;

procedure Foo(P: PDWORD);
begin
end;

procedure Bar;
var
  dw: DWORD;
begin
  Foo(@dw);
end;

begin
end.

компилируется в XE3, но не в XE4, XE5, XE6 и XE7. Ошибка в

Foo(@dw);
[dcc32 Error] E2010 Incompatible types: 'PDWORD' and 'Pointer'

Это кажется странным. Итак, после небольшого копания кажется, что проблема сводится к определению PDWORD. Естественно, можно подумать, что это будет:

PDWORD = ^DWORD;

и это действительно так в XE3. В более поздних версиях мы находим следующее:

// Note: Not ^DWORD yet
PDWORD = ^CppULongInt;

Нечетный. Итак, что такое CppULongInt?

CppULongInt = type LongWord; 
{$EXTERNALSYM CppULongInt 'unsigned long'} 
{$OBJTYPENAME CppULongInt 'Bul' 'Gm'}

Затем, глядя на объявление для DWORD, находим:

//NOTE: DWORD should really be CppULongInt
DWORD = LongWord;

Итак, CppULongInt и DWORD - разные типы. Следовательно, ошибка компиляции.

Что здесь происходит? Какова цель CppULongInt? Почему разработчикам RTL требуется псевдоним DWORD - CppULongInt. Является ли это изменение связано с компилятором x64 Windows С++ на основе LLVM? Я единственный человек в мире, который использует {$TYPEDADDRESS ON}?

Обратите внимание, что последний вопрос является риторическим.

4b9b3361

Ответ 1

Похоже, кто-то в Embarcadero не читал соответствующую документацию Windows:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx

DWORD явно определяется как 32-разрядное целое без знака, поэтому в Delphi он должен быть UInt32. PDWORD определяется как указатель на DWORD, поэтому в Delphi он должен быть PDWORD = ^ DWORD.

Это DWORD_PTR (который не является PDWORD!), который определяется как ULONG_PTR, а последний изменяет размер в зависимости от платформы - Win32 или Win64, а не в определении компилятора un unsigned long.

Одна из причин может заключаться в том, что они пытаются использовать DWORD и другие типы данных Windows на платформах, отличных от Windows, и пытаются поддерживать их совместимость. Если это так, в этом случае они потерпели неудачу и представили ошибку, потому что используемые исправления не будут работать должным образом в Windows.