そのコードはナンセンスで、まったくコンパイルできることに驚いています。3 つのポインター変数を宣言しますが、それらが何かを指すようにすることはありません。これらの変数へのポインターを API 関数に渡しますが、これらの API 関数は、指定した型へのポインターを想定していません。
FileTimeToLocalFileTime
FILETIME
2 つのポインタを受け取ることを期待しています。FileTime
andFileTimeReturn
を値へのポインターとして宣言しましたが、演算子をそれらに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 関数の戻り値をチェックして、次の関数を呼び出す前に成功したことを確認します。
予期しない結果が得られる理由は次のとおりです。AFILETIME
は 64 ビット値です。32 ビット システムを使用している場合、LPFILETIME
変数は 32 ビット幅しかありません。API は 64 ビット幅のバッファーへのポインターを想定していますが、32 ビット空間へのポインターを指定しています。API が 64 ビットの情報を 32 ビット空間に書き込む場合、余分な 32 ビットがどこに格納されているかはわかりません。
へのポインタを渡しましたがSystemTimeReturn
、これはLPSYSTEMTIME
. API は、あたかもSYSTEMTIME
. 次に、関数は であると想定しているものを逆参照しましたが、LPSYSTEMTIME
実際には type の値を保持していましたSYSTEMTIME
。ポインターの代わりに時間を逆参照しました。得られた時間はたまたま有効なアドレスのように見え、その「アドレス」にある値はたまたま 97 です。