In der Anwendung:
Delphi-Quellcode:
type
IHostInterface =
interface
function GetOnShutdown: TList<IDLLClient>;
end;
IDllHostInterface =
interface
procedure Shutdown;
end;
THostInterface =
class(TInterfacedObject, IHostInterface, IDllHostInterface)
private
FOnShutdown: IInterfacedList<IDLLClient>;
function GetOnShutdown: IInterfacedList<IDLLClient>;
public
proedure Shutdown;
// führt Shutdown in allen registrierten DLL-Clients aus
property OnShutdown: IInterfacedList<IDLLClient>
read GetOnShutdown;
end;
In der
DLL:
Delphi-Quellcode:
type
IDLLClient = interface
procedure Shutdown;
end;
TDllClient = class(TInterfacedObject, IDllClient)
public
procedure Shutdown;
end;
procedure InitDll(const AHost: IHostInterface);
var
DllClient: TDllClient;
begin
DllClient := TDllClient.Create;
AHost.OnShutdown.Add(DllClient);
end;
exports
InitDll;
Sprich du übergibst der
DLL z.B. ein Interface, in dem ein Multicast-Event steckt. Wenn du nur eine
DLL hast, reicht natürlich auch ein einfaches Interface statt der Liste. IInterfacedList ist eine Eigenimplementierung, die ich im Büro geschrieben habe, das gibt es bestimmt aber auch schon irgendwo (in Spring4D vielleicht?). Sonst kann man es ja schnell schreiben.
Das Shutdown-Event hat auch direkt einen Sinn. Wenn man die
DLL-Interfaces in Events im Hostinterface hat und die DLLs die Hostinterfaces, werden die Interfaces durch die Gegenseitige Referenz nie freigegeben. Deshalb führe ich vor dem Beenden des Programms den Shutdown-Befehl aus, durch den in der
DLL die Events wieder herausgenommen werden.
(Sauberer wäre die
DLL Klasse im Programm in eine Eventklasse und eine Klasse mit den registrierten DLLs zu trennen... aber das wird hier als Beispiel zu umfangreich...)