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

Ast*_*oth 6 delphi

在我阅读MSDN博客文章之后出现了这个问题,为什么你不能将FILETIME视为__int64?.文章说,将a转换FILETIME为a __int64可以创建一个未对齐的指针.

FILETIME,LUIDLUID_AND_ATTRIBUTES在Windows标头中声明的结构如下:

  typedef struct FILETIME {
      DWORD dwLowDateTime;
      DWORD dwHighDateTime;
  }

  typedef struct LUID {
      ULONG LowPart;
      LONG  HighPart;
  }

  typedef struct LUID_AND_ATTRIBUTES {
      LUID  Luid;
      DWORD Attributes;
  }
Run Code Online (Sandbox Code Playgroud)

由于FILETIMELUID结构具有相似的布局,因此将a 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}
Run Code Online (Sandbox Code Playgroud)

另一个例子是

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

如何安全地处理类似结构FILETIMELUID 直接  为UInt64/ Int64?关键是什么?

Dav*_*nan 5

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

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

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