1

I have a dynamically loaded BPL package which uses a third part library who loads a DLL.

After calling UnloadPackage for my BPL package, the application still locks the DLL file.

var
  MyPackageHandle : THandle;
  MyPackageClass : TPersistentClass;
  MyPackageForm : TCustomForm;
begin
  MyPackageHandle := LoadPackage('.\MyPackage.bpl');
  if(MyPackageHandle <> 0) then 
  begin
    try
      MyPackageClass := GetClass('TMyPackageForm');
      if(Assigned(MyPackageClass) then
      begin
        MyPackageForm := TComponentClass(MyPackageClass).Create(nil) as TCustomForm;
        MyPackageForm.ShowModal();
        MyPackageForm.Free();
      end;
    finally
      UnloadPackage(MyPackageHandle);
    end;
  end;
end;

For testing, I'm using the Windows.GetModuleHandle function.

I've tried calling FreeLibrary passing the handle of the DLL and then I'm able to delete the DLL file. I suspect that a FreeLibrary call is missing somewhere in my BPL package or in the third part BPL.

In a condition like the one described above (A dynamically loaded BPL which statically links a third part BPL which uses a DLL), where should the FreeLibrary be executed?

Fabrizio
  • 7,603
  • 6
  • 44
  • 104
  • It depends where `LoadLibrary` is called. – David Heffernan Jun 26 '19 at 14:08
  • If your BPL calls `LoadLibrary()`, it is responsible for calling `FreeLibrary()` before itself is unloaded. If your BPL does not call `LoadLibrary()`, it is not responsible for calling `FreeLibrary()`. But do make sure you are cleaning up the 3rd party library correctly, if needed. Also, your code is not destroying the `MyPackageForm` object before unloading your BPL. Also, there is no need to define your own `GetModuleHandle()`, the native Win32 `GetModuleHandle()` will work just fine – Remy Lebeau Jun 26 '19 at 17:54
  • @RemyLebeau: Thank you, I've updated the question based on your suggestions – Fabrizio Jun 27 '19 at 06:43
  • @RemyLebeau: I digged in the third part library's source code and found that in each third part component's constructor, if it doesn't already exists, they create a main object which is shared between all the components of the third part library. This object in his constructor calls `LoadLibrary` and in it's destructor calls `FreeLibrary`. In this logic, I think that the last third part component should free the shared object in its destructor but it's not happening – Fabrizio Jun 27 '19 at 06:44
  • @RemyLebeau: I prefer to do not change this third part library's source code, I think to fix this problem by freeing the shared object when unloading the MyPackage BPL, I've created a [separated question](https://stackoverflow.com/questions/56785458/how-to-detect-unloadpackage-from-the-target-bpl) for detecting the package unloading – Fabrizio Jun 27 '19 at 06:54
  • @Fabrizio sounds like either the 3rd party library is not managing its shared object correctly, or maybe your BPL's code is leaking some resource from the library that prevents that share object from being freed correctly – Remy Lebeau Jun 27 '19 at 17:34

0 Answers0