德尔福7. 如何在不重新启动应用程序的情况下卸载dll?

krt*_*rtl 2 delphi dll

我需要在不重新启动应用程序的情况下替换我的 dll,但是在 FreeLibrary 之后它仍然在使用并且无法删除。

请帮忙。

//...
function MyFunc(): PChar; stdcall; external 'MyDll.dll';

implementation

//...

hDLL := LoadLibrary('MyLib.dll');
if hDLL = 0 then
  Begin
    LogError('Can''t load MyLib.dll!');
    exit;
  end;

try
  MyFunc();
finally
  FreeLibrary(hDLL);
end;

if not DeleteFile('MyLib.dll') then
  LogError('Can''t delete MyLib.dll!');
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 5

首先,让我们澄清一个非常常见的错误。你写:

if hDLL < 32 then
Run Code Online (Sandbox Code Playgroud)

这不是加载DLL 时测试失败的方法。正如 的 文档中非常清楚地指出的LoadLibrary,失败由返回值 表示NULL,在 Delphi 术语中为0。因此,您应该将该测试替换为:

if hDLL = 0 then
Run Code Online (Sandbox Code Playgroud)

除此之外,只要每次调用都LoadLibrary与匹配的调用配对FreeLibrary,就可以删除该文件。

因此,有其他原因阻止您删除它。例如,这可能是:

  • 该 DLL 位于您的用户无权删除它的目录中。
  • 另一个进程已加载该 DLL。
  • 您的进程已通过其他方式加载了 DLL,因此仍然保留对它的引用。
  • 该 DLL 不位于当前工作目录中。由于您使用了相对路径,因此在加载 DLL 时将使用 DLL 搜索路径,但在尝试删除它时将使用工作目录。这些可能不一致。

请注意,此列表并不详尽。

您现在需要进行一些调试。您面临着调用DeleteFile失败的情况。所以,问问系统为什么。

if not DeleteFile('MyLib.dll') then
  LogError(Format('Can''t delete MyLib.dll, error code = %d', [GetLastError]));
Run Code Online (Sandbox Code Playgroud)