0

我有一个返回 SYSTEMTIME 的函数。

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 年。为什么?

4

1 回答 1

3

该代码是胡说八道,我很惊讶它完全可以编译。你声明了三个指针变量,但你从来没有让它们指向任何东西。您将指向这些变量的指针传递给 API 函数,但这些 API 函数并不期望指向您提供的类型的指针。

FileTimeToLocalFileTime期望收到两个FILETIME指针。您已将FileTimeand声明FileTimeReturn为指向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;

Note that I've removed the LP prefixes from the type names, and I've removed the dereference from the final line.

Correct code would check each API function's return value to make sure it succeeded before calling the next one.


Here's why you get the unexpected results you see. A FILETIME is a 64-bit value. If you're using a 32-bit system, then your LPFILETIME variables are only 32 bits wide. The API expects a pointer to a 64-bit-wide buffer, but you're giving it a pointer to a 32-bit space. When the API writes 64 bits of information into a 32-bit space, we can't be sure where the extra 32 bits are being stored.

You passed a pointer to SystemTimeReturn, which was an LPSYSTEMTIME. The API wrote into that space as though it were a SYSTEMTIME. Then, your function dereferenced what it assumed to be an LPSYSTEMTIME, but which actually held a value of type SYSTEMTIME. You dereferenced a time instead of a pointer. The time you got happens to look like a valid address, and the value residing at that "address" happens to be 97.

于 2012-09-06T21:31:13.047 回答