krtl
krtl

Reputation: 203

Delphi7. How to unload dll without app restarting?

I need to replace my dll without restarting of app, but after FreeLibrary it is still used and cannot be deleted.

Please help.

//...
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!');

Upvotes: 2

Views: 2375

Answers (1)

David Heffernan
David Heffernan

Reputation: 613562

First of all, let's clear up a very common mistake. You write:

if hDLL < 32 then

This is not how to test for failure when loading a DLL. As stated very clearly in the documentation for LoadLibrary, failure is indicated by a return value of NULL, which in Delphi terms is 0. So you should replace that test with:

if hDLL = 0 then

Beyond that, so long as each call to LoadLibrary is paired with a matching call to FreeLibrary, then it is possible to delete the file.

So, something else is stopping you from deleting it. For instance that might be:

  • The DLL is located in a directory where your user does not have rights to delete it.
  • Another process has loaded the DLL.
  • Your process has loaded the DLL by some other means and therefore still holds a reference to it.
  • The DLL is not located in the current working directory. Because you used a relative path, the DLL search path is used when you load the DLL, but the working directory is used when you attempt to delete it. These might not coincide.

Note that this list is not exhaustive.

You need to do some debugging now. You are faced with a situation where a call to DeleteFile fails. So, ask the system why.

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

Upvotes: 5

Related Questions