为什么PDWord不是^ DWORD?

时间:2014-09-12 21:47:54

标签: delphi delphi-xe4

这个程序

{$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;

因此,CppULongIntDWORD是不同的类型。因此编译错误。

这里发生了什么? CppULongInt的目的是什么?为什么RTL设计者似乎希望将DWORD别名为CppULongInt。此更改是否与基于LLVM的x64 Windows C ++编译器相关?我是世界上唯一使用{$TYPEDADDRESS ON}的人吗?

请注意,最后一个问题是修辞。

1 个答案:

答案 0 :(得分:5)

看来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而改变 - 而不是编译器的定义未签名的长期。

一个原因可能是他们试图在非Windows平台上使用DWORD和其他Windows数据类型,并且正在尝试保持它们兼容。如果是这样,在这种情况下,他们失败并引入了一个错误,因为使用的定义在Windows中无法正常工作。