Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi DLL entladen (https://www.delphipraxis.net/64710-dll-entladen.html)

hanspeter 7. Mär 2006 10:01


DLL entladen
 
Kann sich eigentlich eine Dll selbst entladen?

Ich bin dabei Forms in eine DLL auszulagern.
Sind diese mit Show geöffnet, soll die Dll beim Schließen des Form
entladen werden.

Bisher mache ich das beim Schließen der Form (Action := cafree) mit einer
Message bzw. einen Callback an das aufrufende Programm.
Das Parent übergebe ich ohnehin.
Und bitte keinen Hinweis, das es mit BPL alles besser geht.
Der Einsatz von Dll statt BPL hat Gründe.

Gruß
Peter

shmia 7. Mär 2006 10:22

Re: DLL entladen
 
Du öffnest die DLL mit LoadLibrary und bekommst ein Handle.
Mit CloseLibrary(handle) wird die DLL geschlossen; wo ist also das Problem ?

hanspeter 7. Mär 2006 10:45

Re: DLL entladen
 
Zitat:

Zitat von shmia
Du öffnest die DLL mit LoadLibrary und bekommst ein Handle.
Mit CloseLibrary(handle) wird die DLL geschlossen; wo ist also das Problem ?

So mache ich das ja jetzt.
(CloseLibrary gibt es übrigens nicht)
Das Problem ist, wenn ich ein formular mit Show anzeige, dann ist das für eine unbestimmte Zeit geöffnet und wird spätestens bei Programmende mit FreeLibrary entfernt.
Wird zur Lebzeit des Programmes das Formular geschlossen, so rufe ich jetzt über einen Callback
das übergeordnete Programm, um dort ein FreeLibrary zu veranlassen. Das muß noch Zeitverzögert
sein, damit dem Callback nicht der Boden weggezogen wird.

Mich interessiert, ob es die Möglichkeit gibt, dass sich die Dll selbst entläd.
Bzw. was passiert, wenn Freelibrary in der DLL selbst steht?

Gruß Peter

shmia 7. Mär 2006 12:48

Re: DLL entladen
 
Zitat:

Zitat von hanspeter
Das Problem ist, wenn ich ein formular mit Show anzeige, dann ist das für eine unbestimmte Zeit geöffnet und wird spätestens bei Programmende mit FreeLibrary entfernt.
Wird zur Lebzeit des Programmes das Formular geschlossen, so rufe ich jetzt über einen Callback
das übergeordnete Programm, um dort ein FreeLibrary zu veranlassen. Das muß noch Zeitverzögert
sein, damit dem Callback nicht der Boden weggezogen wird.

Die DLL muss auf jeden Fall aus dem Kontext der Hauptanwendung geschlossen werden.
Anstelle einen Callback kannst du auch eine Windows-Message verwenden.
Dies erspart dir die Zeitverzögerung.
Delphi-Quellcode:
// im Hauptprogram
const
   UM_UNLOAD_DLL = WM_USER + 100;
type
TMainForm = class(TForm)

   procedure UMUnloadDLL(var msg: TMessage); message UM_UNLOAD_DLL;

end;
...
procedure TMainForm.UMUnloadDLL(var msg: TMessage);
begin
   ShowMessage('DLL entladen');
   FreeLibrary(DLLhandle);
end;
Damit die DLL weiss, an welches Window die Message geschickt werden soll,
muss du das Handle des Hauptformulars irgendwie der DLL mitteilen.
Delphi-Quellcode:
// und in der DLL
const
   UM_UNLOAD_DLL = WM_USER + 100;

procedure TDLLForm.FormDestroy(Sender: TObject);
begin
   // Mitteilung an Hauptformular der Anwendung, dass die DLL
   // jetzt entladen werden kann.
   PostMessage(FMainformhandle, UM_UNLOAD_DLL, 0, 0);
end;
Übrigens:
Wenn du ActiveX-DLLs verwendest, dann wird das Freigeben der DLL vom
Betriebssystem übernommen. Allerdings wird eine ActiveX DLL nicht sofort
entladen, sondern erst nach einer bestimmten Haltezeit.

hanspeter 7. Mär 2006 13:18

Re: DLL entladen
 
Danke für die Tips.
Mit Postmessage hatte ich schon experimentiert. Hat auch funktioniert.
Bei dem Callback bin ich gelandet, weil ich einen Dll Handler für das Programm
geschrieben habe (und ein Modul auf Dll Seite)
1. Die Dll wird mit Loadlibrary erzeugt.
2. Es wird Aplication.Handle, Parenhandle und Dll-Handle übergeben.
3. Die Form wird mit Show angezeigt.
4. Bei Close der Form in der Dll wird die Form mit Action := cafree freigegeben.
5. Das aufrufende Programm (hier der Dll Handler) wird über Callback informiert, dass die
Dll freigegeben werden kann. Dazu wird das eigene (vorherübergebenen DLL-Handle als Kennung
benutzt.
Kann man eigentlich in der Dll das Handle derselben herausbekommen?

Der Vorschlag mit Messages und PostMessage ist eleganter. Hier habe ich jedoch das Problem,
dass mein DLL Handler nicht von Twincontrol abstammt und keine Botschaften empfangen kann.
Hier müßte ich dann im Mainfenster der Anwendung die Botschaft abfangen und zum dem
Handler durchschleifen.

BPL möchte ich aus zwei Gründen nicht verwenden.
1. Ohne eine automatische Updatekontrolle ist das System zu störanfällig.
Das Programm muß unter sehr robusten Umgebungsbedingungen laufen und das fast immer am
Wochenende. Ein Internetzugang steht meist nicht zur Verfügung.
Die Beziehungen zwischen Hauptpgrogramm und Dll sind so lose, dass eigentlich nur der
Datenbankname (Firebird) und eine ID zu übergeben sind.

2. Sollte ich in absehbarer Zeit gezwungen sein, auf Net überzugehen, dann kann ich große
Teile des Programms (die Dll) erst einmal weiternutzen.

Kennt wehr übrigends ein brauchbares (auch kostenpflichtiges) DLL Framework?

Gruß
Peter

teebee 7. Mär 2006 13:37

Re: DLL entladen
 
Zitat:

Zitat von hanspeter
Der Vorschlag mit Messages und PostMessage ist eleganter. Hier habe ich jedoch das Problem,
dass mein DLL Handler nicht von Twincontrol abstammt und keine Botschaften empfangen kann.
Hier müßte ich dann im Mainfenster der Anwendung die Botschaft abfangen und zum dem
Handler durchschleifen.

Vielleicht hilft Dir AllocateHwnd aus Classes.pas. Ein Beispiel findest du in der Implementation von TTimer in ExtCtrls.pas.
Gruß, teebee

Robert Marquardt 7. Mär 2006 13:51

Re: DLL entladen
 
Bei AllocateHWnd unbedingt das Beispiel in der Hilfe ansehen. Man muss DefWindowProc fuer alle Messages aufrufen.
Wenn man das nicht macht gibt es z. B. Probleme mit dem Windows-Shutdown. Das Fenster unterbricht naemlich dann den Shutdown.

hanspeter 7. Mär 2006 15:30

Re: DLL entladen
 
[quote="Robert Marquardt"]Bei AllocateHWnd unbedingt das Beispiel in der Hilfe ansehen. Man muss DefWindowProc fuer alle Messages aufrufen.
quote]

Danke für den Tip.
Du glücklicher. Im Profil sehe ich, dass Du noch mit D6 arbeitest.
Beispiel in Hilfe ist in D2006 nicht mehr.
Irgendwo habe ich aber noch ein D7 installiert.

Gruß Peter


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:05 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz