GdiPlusShutdown (and GdiPlusStartup btw) cannot be called from DllMain, but DllMain is called by Windows and Delphi at runtime when FreeLibrary is called: Delphi calls the completion section of all blocks used by the DLL and GdiPlus finalization sections, calls GdiPlusShutdown (this is fine OK when used from executable file). Similar behavior with the initialization section.
I fixed the problem by adding a test for IsLibrary in the initialization and completion sections to avoid invoking the violating functions, I also added two public procedures InitializeForDll and FinalizeForDll. With these small changes, the DLL can export functions that call InitializeForDll and FinalizeForDll. These exported functions should be called by the hosting application immediately after loading the DLL and immediately before the DLL is unloaded.
Here are the changes I made to GdiPlus.pas:
In the interface section:
var procedure InitializeForDll; procedure FinalizeForDll;
In the implementation section:
procedure InitializeForDll; begin Initialize; end; procedure FinalizeForDll; begin Finalize; end;
The initialization and completion sections have also been updated:
Initialization if not IsLibrary then Initialize; Finalization if not IsLibrary then Finalize;
In the DLL, I exported these functions:
procedure Initialize; stdcall; begin GdiPlus.InitializeForDll; end; procedure Finalize; stdcall; begin GdiPlus.FinalizeForDll; end;
Initialization and termination is called by the hosting application immediately after calling LoadLibrary and immediately before calling FreeLibrary (or whatever the DLL will load / unload).
Hope this helps others. btw: Thanks to Eric Bilsen for providing the Delphi GdiPlus Library
source share