delphi 为什么PDWord不是^DWORD?

jhiyze9q  于 2023-06-22  发布在  其他
关注(0)|答案(1)|浏览(144)

这个程序

{$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}的人吗?
注意,最后一个问题是反问句。

wko9yo5t

wko9yo5t1#

(参考Why PDWORD is not a pointer to DWORD。)看起来Embarcadero的某个人没有阅读相关的Windows文档:

  • DWORD被明确定义为 32unsigned integer,因此在 Delphi 中它应该是UInt32
  • PDWORD被定义为指向DWORD的指针,因此在 Delphi 中应该是PDWORD = ^DWORD
  • 它是DWORD_PTR(不是PDWORD!),后者的大小取决于 * 平台 *(32或64位),而不是unsigned long的编译器定义。

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

相关问题