2012-09-06 40 views
0

我有一個返回SYSTEMTIME的函數。Pascal - Win32api SYSTEMTIME struct wYear始終是97

function GetFileDate : SYSTEMTIME; //Stdcall; 
var 
    CheckFile: Long; 
    FileTime: LPFILETIME; 
    FileTimeReturn: LPFILETIME; 
    SystemTimeReturn: LPSYSTEMTIME; 
begin 
    CheckFile := CreateFile(PChar('main.dll'), GENERIC_READ, FILE_SHARE_READ, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
    GetFileTime(CheckFile, @FileTime, NIL, NIL); 
    FileTimeToLocalFileTime(@FileTime, @FileTimeReturn); 
    FileTimeToSystemTime(@FileTime, @SystemTimeReturn); 
    GetFileDate := SystemTimeReturn^; 
end; 

對於2012年和2006年以及其他任何文件,它總是會返回97年。 爲什麼?

+0

購買Apple股票。這在幾年內是值得的;)PS:帶「LP」的類型通常意味着「長指針」;即32位地址。您可能需要「FILETIME」或「SYSTEMTIME」記錄; *不是*「LPFILETIME」;) – paulsm4

+0

如果你看到[你的最後一個問題]的最新答案(http://stackoverflow.com/questions/12291076/pascal-get-field-from-lpsystemtime-record)首先看看這段代碼有什麼問題,並找到解決這個問題的方法。 (有一個原因是你的問題通知你有新的內容 - 這是你可以檢查的內容。):-) –

+0

有多尷尬。抱歉。 –

回答

3

該代碼是無稽之談,我很驚訝它編譯。你聲明瞭三個指針變量,但你永遠不會讓它們指向任何東西。您將指向這些變量的指針傳遞給API函數,但這些API函數並不期望指向您給它們的類型。

FileTimeToLocalFileTime預計會收到兩個FILETIME指針。您已將FileTimeFileTimeReturn指定爲指向FILETIME值的指針,但是當您將@運算符應用於它們時,將獲得指針以指向FILETIME值。更好的代碼應該是這樣的:

function GetFileDate : SYSTEMTIME; //Stdcall; 
var 
    CheckFile: Long; 
    FileTime: FILETIME; 
    FileTimeReturn: FILETIME; 
    SystemTimeReturn: SYSTEMTIME; 
begin 
    CheckFile := CreateFile(PChar('main.dll'), GENERIC_READ, FILE_SHARE_READ, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
    GetFileTime(CheckFile, @FileTime, NIL, NIL); 
    FileTimeToLocalFileTime(@FileTime, @FileTimeReturn); 
    FileTimeToSystemTime(@FileTime, @SystemTimeReturn); 
    GetFileDate := SystemTimeReturn; 
end; 

請注意,我已經移除了類型名稱的前綴LP,我已經移除了最後一行反引用。

正確的代碼會檢查每個API函數的返回值,以確保它在調用下一個函數之前成功。


這就是爲什麼你會看到意想不到的結果。 A FILETIME是一個64位值。如果您使用的是32位系統,那麼您的LPFILETIME變量只有32位寬。 API需要一個指向64位寬緩衝區的指針,但是您要給它一個指向32位空間的指針。當API將64位信息寫入32位空間時,我們無法確定額外的32位存儲在哪裏。

你傳遞了​​一個指針SystemTimeReturn,這是一個LPSYSTEMTIME。 API寫入該空間,就好像它是一個SYSTEMTIME。然後,您的函數取消了它假定的LPSYSTEMTIME,但實際上保留了SYSTEMTIME類型的值。你取消了一個時間而不是一個指針。你碰巧看起來像一個有效的地址,並且該「地址」的值恰好是97.

+0

+1。看到這張海報的最後一個問題在http://stackoverflow.com/questions/12291076/pascal-get-field-from-lpsystemtime-record - 雷米Lebeau也糾正了這個問題,但顯然SuperDisk沒有檢查新的內容。 :-) –

+0

@KenWhite當我提出這個問題時,他沒有發佈編輯。對不起,如果所有這些帕斯卡爾Winapi的東西聽起來像完全白癡,我只是想抓住帕斯卡爾。 –

+0

沒關係。雷米的第二個回答並沒有真正回答你問的問題。它回答了你在這裏問到的問題,這與你之前詢問的完全不同。一個是編譯器錯誤,另一個是運行時錯誤。你發表這個問題是正確的。您不需要在其他問題中發佈函數體,因爲它不會影響編譯器錯誤。 –