使用来自 Remy Lebeau 评论的信息,我SetErrorMode
在 Delphi 6 中试验了函数。
该设置包括三个项目:
- 动态链接调用者 DLL 的宿主应用程序,
- 调用者 DLL,静态链接工作 DLL,
- 和一个工人 DLL。
首先,我将两个 DLL 都放在主机应用程序文件夹中,测试一切正常,然后删除工作 DLL 并在没有它的情况下进行测试。
这是一些代码:
主机应用程序
program MyHost;
uses
Windows, SysUtils;
var
hLib: HMODULE;
procedure Box(msg: WideString);
begin
MessageBoxW(0, PWideChar(msg), 'MyHost Message', 0);
end;
procedure ShowLastError();
begin
Box('LastError: ' + SysErrorMessage(GetLastError()));
end;
type
TDoWork = procedure();
var
DoWork: TDoWork;
begin
SetErrorMode(SEM_FAILCRITICALERRORS);
try
{Without SetErrorMode it displays modal dialog.
No exception is generated.
After clicking at [Ok], it goes to "if hLib = 0".
With SetErrorMode it just goes to "if hLib = 0"}
hLib := LoadLibrary('CallerLib.dll');
if hLib = 0 then begin
ShowLastError();
Halt(1);
end;
try
@DoWork := GetProcAddress(hLib, 'DoWork');
if @DoWork <> nil then DoWork();
finally
FreeLibrary(hLib);
end;
except
on ex: Exception do Box(ex.ClassName + ': ' + ex.Message);
end;
end.
调用者 DLL
library CallerLib;
uses
Windows;
//Static linking
procedure Function1(); stdcall; external 'MyLib.dll';
procedure Function2(); stdcall; external 'MyLib.dll';
//To be dynamically linked
procedure DoWork(); stdcall; export;
begin
Function1();
Function2();
end;
exports
DoWork;
end.
工作程序 DLL
library MyLib;
uses
Windows;
procedure Function1(); stdcall; export;
begin
MessageBox(0, 'MyDLL.Function1', 'MyDLL', 0);
end;
procedure Function2(); stdcall; export;
begin
MessageBox(0, 'MyDLL.Function2', 'MyDLL', 0);
end;
exports
Function1, Function2;
end.