【发布时间】:2017-04-06 02:36:49
【问题描述】:
在调用ExtractShortPathName 之类的Windows API 函数包装器后使用GetLastError 时,我注意到GetLastError 返回一个非零错误代码,无论对ExtractShortPathName 的调用是成功还是失败。事实上,在我的程序执行之前似乎有一个“最后一个错误”,例如
program TestGetLastError;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
var
ErrorCode: Integer;
begin
try
ErrorCode := GetLastError;
if ErrorCode <> 0 then
RaiseLastOSError;
except
on E: Exception do
WriteLn(E.ClassName, ': ', E.Message);
end;
end.
结果:
EOSError: System Error. Code: 122.
The data area passed to a system call is too small
我是误会了什么还是做错了什么?
如果 Delphi 运行时正在执行导致设置 GetLastError 的操作,那么在我的程序开始执行之前清除该错误的正确方法是什么?我应该像 Delphi API 文档中的这个例子那样使用SetLastError(ERROR_SUCCESS);:
procedure TForm2.btRaiseLastClick(Sender: TObject);
begin
{ Set the last OS error to a bogus value. }
System.SetLastError(ERROR_ACCESS_DENIED);
try
RaiseLastOSError();
except
on Ex : EOSError do
MessageDlg('Caught an OS error with code: ' + IntToStr(Ex.ErrorCode), mtError, [mbOK], 0);
end;
{ Let the Delphi Exception dialog appear. }
RaiseLastOSError(ERROR_NOT_ENOUGH_MEMORY);
{ Finally set the last error to none. }
System.SetLastError(ERROR_SUCCESS);
if GetLastError() <> ERROR_SUCCESS then
MessageDlg('Whoops, something went wrong in the mean time!', mtError, [mbOK], 0);
{ No exception should be thrown here because last OS error is "ERROR_SUCCESS". }
CheckOSError(GetLastError());
end;
http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/LastOSError_(Delphi)
【问题讨论】:
-
除非发生故障,否则不要调用 GetLastError。毫无意义。
-
我得到了完全相同的结果。有趣的是,当我从uses 子句中删除
SysUtils(以及所有需要它的)时,我得到错误代码50(The request is not supported.)。但是@Jonathan 是对的,除非实际发生错误,否则没有理由致电GetLastError。想象一下 10 分钟前在完全不同的窗口中发生的错误。然后,无论出于何种原因,您调用GetLastError,从而返回与 10 分钟前相同的代码。 -
API 文档表明 GetLastError 仅在 a) API 调用失败时使用,并且 b) 失败的函数表明您可以使用 GetLastError 获取有关原因的更多信息。随机调用它或在记录将其设置为失败的函数中调用它而没有失败是没有意义的。除非您知道发生了错误,否则您不能调用 GetLastError,并且只有在您调用的特定函数表明它失败后才调用它。
-
那么我是误会了什么还是做错了什么?的答案是两者都。 :-)
-
@KendallLister
ExtractShortPathName不是 Windows API 调用,它是 Delphi SysUtils 内置的,而后者又调用GetShortPathName,这是一个 API 调用:)
标签: delphi winapi error-handling delphi-xe8