2012-11-21 22 views
6

Câu hỏi nảy sinh sau khi tôi đọc một bài viết trên MSDN Blog, Why can't you treat a FILETIME as an __int64?. Bài viết nói rằng việc đúc một số FILETIME đến một số __int64 có thể tạo một con trỏ không được căn chỉnh.Xử lý các cấu trúc như FILETIME dưới dạng UInt64/Int64

FILETIME, LUID, và LUID_AND_ATTRIBUTES struct tuyên bố trong Windows tiêu đề như sau:

typedef struct FILETIME { 
     DWORD dwLowDateTime; 
     DWORD dwHighDateTime; 
    } 

    typedef struct LUID { 
     ULONG LowPart; 
     LONG HighPart; 
    } 

    typedef struct LUID_AND_ATTRIBUTES { 
     LUID Luid; 
     DWORD Attributes; 
    } 

Kể từ FILETIMELUID cấu trúc có một bố cục tương tự, do đó điều trị một LUID như một __int64 cũng có thể tạo ra một con trỏ lệch. Tuy nhiên, Windows.pas (Delphi XE3 đây) thực hành này--, ví dụ:

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

ví dụ khác là

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

Làm thế nào để điều trị một cách an toàn cấu trúc như FILETIME hoặc LUID trực tiếp   như UInt64/Int64? Chìa khóa là gì?

Trả lời

5

Đó là một vấn đề không quan trọng đối với kiến ​​trúc mà Delphi hỗ trợ. Các kiến ​​trúc x86 và x64 tha thứ cho bạn nếu bạn truy cập dữ liệu sai lệch. Mặt khác, việc truy cập dữ liệu sai lệch trên Itanium sẽ dẫn đến lỗi thời gian chạy. Nhưng Delphi không bao giờ nhắm vào Itanium.

Vấn đề quan trọng là bố cục bản ghi. Int64 có liên kết 8. Nhưng FILETIME và LUID có căn chỉnh 4. Đó là lý do LUID_AND_ATTRIBUTES được đánh dấu rõ ràng $ ALIGN 4.

Nếu bạn định khai báo FILETIME và LUID thành Int64 thì bạn cần phải chăm sóc đặc biệt với bố cục kỷ lục mỗi khi bạn bao gồm một bản ghi trong một bản ghi.

+0

@David_Heffernan, giải thích rất rõ, cảm ơn. – Astaroth

Các vấn đề liên quan