6

在我阅读了一篇 MSDN 博客文章后出现了问题,为什么不能将 FILETIME 视为 __int64?. 文章说,将 aFILETIME转换为 an__int64会产生未对齐的指针。

FILETIME, LUID, 和LUID_AND_ATTRIBUTESWindows 标头中声明的结构如下:

  typedef struct FILETIME {
      DWORD dwLowDateTime;
      DWORD dwHighDateTime;
  }

  typedef struct LUID {
      ULONG LowPart;
      LONG  HighPart;
  }

  typedef struct LUID_AND_ATTRIBUTES {
      LUID  Luid;
      DWORD Attributes;
  }

由于FILETIMEand LUIDstructs 具有相似的布局,因此将 aLUID视为 an__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?关键是什么?

4

1 回答 1

5

在 Delphi 支持的架构上,这在很大程度上不是问题。如果您访问未对齐的数据,x86 和 x64 架构会原谅您。另一方面,访问 Itanium 上未对齐的数据将导致运行时错误。但德尔福从未针对安腾。

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

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

于 2012-11-21T07:07:57.997 回答