在我阅读MSDN博客文章Why can't you treat a FILETIME as an __int64?之后,出现了这个问题。文章说,向FILETIME
投射__int64
可能会导致指针错位。
FILETIME
,LUID
和LUID_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;
}
由于FILETIME
和LUID
结构具有相似的布局,因此将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
如何将FILETIME
或LUID
等结构安全地直接 作为UInt64
/ Int64
?关键是什么?
答案 0 :(得分:5)
Delphi支持的体系结构基本上没有问题。如果您访问错误对齐的数据,x86和x64架构会原谅您。另一方面,访问Itanium上的错误对齐数据将导致运行时错误。但Delphi从未针对安腾。
重要的问题是记录布局。 Int64的对齐方式为8.但FILETIME和LUID的对齐方式为4.这就是LUID_AND_ATTRIBUTES标记为显式$ ALIGN 4的原因。
如果您要将FILETIME和LUID声明为Int64,那么每次在记录中包含一个记录布局时,您都需要特别小心。