简体   繁体   English

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

[英]Treating structs like FILETIME as UInt64/Int64

The question arise after I read a MSDN Blog article, Why can't you treat a FILETIME as an __int64? 在我阅读MSDN博客文章之后出现了这个问题, 为什么你不能将FILETIME视为__int64? . The article said that casting a FILETIME to an __int64 can create a misaligned pointer. 文章说,将一个FILETIME转换为__int64会产生一个未对齐的指针。

FILETIME , LUID , and LUID_AND_ATTRIBUTES structs declared in Windows header as follows: 在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;
  }

Since FILETIME and LUID structs has a similar layout, therefore treating a LUID as an __int64 also can create a misaligned pointer. 由于FILETIMELUID结构具有类似的布局,因此将LUID视为__int64也可以创建未对齐的指针。 However, Windows.pas (Delphi XE3 here) practises this--, for example: 但是, Windows.pas (这里是Delphi XE3)实现了这一点 - 例如:

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

another example is 另一个例子是

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

How to safely treat structs like FILETIME or LUID directly as UInt64 / Int64 ? 如何安全地将结构如FILETIMELUID 直接作为UInt64 / Int64 What is the key? 关键是什么?

It's a largely non-issue on the architectures that Delphi supports. 这在Delphi支持的架构上基本上没有问题。 The x86 and x64 architectures forgive you if you access mis-aligned data. 如果您访问错误对齐的数据,x86和x64架构会原谅您。 On the other hand, accessing mis-aligned data on Itanium will result in runtime errors. 另一方面,访问Itanium上的错误对齐数据将导致运行时错误。 But Delphi never targeted Itanium. 但Delphi从未针对Itanium。

The issue that is significant is record layout. 重要的问题是记录布局。 An Int64 has alignment of 8. But FILETIME and LUID have alignment of 4. Which is why LUID_AND_ATTRIBUTES is marked with an explicit $ALIGN 4. Int64的对齐方式为8.但FILETIME和LUID的对齐方式为4.这就是LUID_AND_ATTRIBUTES标记为显式$ ALIGN 4的原因。

If you are going to declare FILETIME and LUID to be Int64 then you need to take special care with record layout every time you include one in a record. 如果您要将FILETIME和LUID声明为Int64,那么每次在记录中包含一个时,您需要特别注意记录布局。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM