将FILETIME之类的结构视为UInt64 / Int64

时间:2012-11-21 06:23:45

标签: delphi

在我阅读MSDN博客文章Why can't you treat a FILETIME as an __int64?之后,出现了这个问题。文章说,向FILETIME投射__int64可能会导致指针错位。

在Windows标头中声明的

FILETIMELUIDLUID_AND_ATTRIBUTES结构如下:

  typedef struct FILETIME {
      DWORD dwLowDateTime;
      DWORD dwHighDateTime;
  }

  typedef struct LUID {
      ULONG LowPart;
      LONG  HighPart;
  }

  typedef struct LUID_AND_ATTRIBUTES {
      LUID  Luid;
      DWORD Attributes;
  }

由于FILETIMELUID结构具有相似的布局,因此将LUID视为__int64也会产生错位指针。但是,Windows.pas(这里是Delphi XE3)实现了这一点 - 例如:

  {$ALIGN 4}
  LUID_AND_ATTRIBUTES = record
    Luid      : Int64;  // Here, LUID is treated as Int64
    Attributes: DWORD;
  end;
  {$ALIGN ON}

另一个例子是

  function LookupPrivilegeValue(lpSystemName, lpName: LPCWSTR;
      var lpLuid: Int64): BOOL; stdcall; // LUID is treated as Int64

如何将FILETIMELUID 等结构安全地直接 作为UInt64 / Int64?关键是什么?

1 个答案:

答案 0 :(得分:5)

Delphi支持的体系结构基本上没有问题。如果您访问错误对齐的数据,x86和x64架构会原谅您。另一方面,访问Itanium上的错误对齐数据将导致运行时错误。但Delphi从未针对安腾。

重要的问题是记录布局。 Int64的对齐方式为8.但FILETIME和LUID的对齐方式为4.这就是LUID_AND_ATTRIBUTES标记为显式$ ALIGN 4的原因。

如果您要将FILETIME和LUID声明为Int64,那么每次在记录中包含一个记录布局时,您都需要特别小心。