In einem Programm verwende ich u.a. den Virtualtreeview.
Im Finalization Teil der Unit virtualtrees.pas wird eine Bitmap freigegeben. Im Verlauf dessen wird die function DeleteObject(GDIObject: HGDIOBJ): Boolean; aufgerufen, welche wiederum WidgetSet.DeleteObject(GDIObject); aufruft. Zu diesem Zeitpunkt ist aber die Variable widgetset bereits nil. (Wird in Forms.FreeWidgetSet freigegeben und auf nil gesetzt). Das führt natürlich zu einer Zugriffsverletzung.
Soweit mir bekannt ist, werden die finalization Abschnitte in der umgekehrten Reihenfolge der Einbindung der Units aufgerufen.
Dabei ist aber die Unit Forms die erste eingebundene Unit und virtualtrees die letzte.
Ist das ein Fehler oder kann das andere Ursachen haben?
Mein System ist Lazarus 4.7 (rev lazarus_4_6-58-g310cad12d8) FPC 3.2.2 i386-win32-win32/win64
[gelöst] Reihenfolge der finalization?
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1787
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
[gelöst] Reihenfolge der finalization?
Zuletzt geändert von fliegermichl am Di 9. Jun 2026, 13:59, insgesamt 1-mal geändert.
Re: Reihenfolge der finalization?
Kannst du versuchen, das in einem kleinen Projekt zu reproduzieren und hochzuladen? Bei allem, was ich mit VTV gemacht habe, ist so ein Fehler noch nie aufgetreten.
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1787
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: Reihenfolge der finalization?
Hat sich erledigt.
Irgendwie ist in der lpr Datei das einbinden der unit interfaces hinter forms geraten und in interfaces.finalization wird FreeWidgetSet aufgerufen.
Irgendwie ist in der lpr Datei das einbinden der unit interfaces hinter forms geraten und in interfaces.finalization wird FreeWidgetSet aufgerufen.
-
PascalDragon
- Beiträge: 1043
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: [gelöst] Reihenfolge der finalization?
Nicht ganz. Was richtig ist, ist dass die finalization-Abschnitte in umgekehrter Reihenfolge zu den initialization-Abschnitten aufgerufen werden und dass Units, die in der interface-Sektion gelistet sind, vor der aktuellen Unit initialisiert werden. Die genaue Reihenfolge kann sich auf Grund der konkreten Units und deren Abhängigkeiten jedoch von der erwarteten unterscheiden.fliegermichl hat geschrieben: Di 9. Jun 2026, 11:08 Soweit mir bekannt ist, werden die finalization Abschnitte in der umgekehrten Reihenfolge der Einbindung der Units aufgerufen.
FPC Compiler Entwickler
-
Warf
- Beiträge: 2305
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: [gelöst] Reihenfolge der finalization?
Im Grunde ist das mit der Initialisierung und Finalisierung recht einfach. Jede Source Datei beschreibt ihre Abbhängigkeiten über die Uses Klausel. Da jede Unit die in Uses steht selbst Uses haben kann bildet das eine Baumstruktur.
Als Beispiel, sagen wir mal wir haben das Hauptprogramm (lpr Datei) mit Uses "Unit1, Unit2, Unit3". Unit1 nutzt Intern "Unit2, Unit1b", Unit2 nutzt "Unit2a, Unit2b" und Unit3 nutzt nichts. Dann ist der entsprechende Graph:
Zum initialisieren wird jetzt einfach eine Tiefensuche gemacht, bei der Units die bereits schon Initialisiert wurden übersprungen werden. Also es wird Main.lpr geschaut, das hat 3 uses, also geht der in den ersten (Unit1.pas), die wiederum 2 uses hat. Da geht es dann in den ersten, und dann wieder und ist dann bei Unit2a.pas. Danach dann Unit2b.pas, dann sind alle dependencies von Unit2 erfüllt und die kann initialisiert werden. Danach Unit1b.pas und dann endlich Unit1.
Danach ist Unit2.pas im Hauptprogramm dran, die wurde aber schon initialisiert, daher kann das übersprungen werden und Unit3.pas angefangen werden. Wenn die Fertig ist sind alle Dependencies von Main.lpr erfüllt und der Code kann ausgeführt werden.
Die letztendliche Reihenfolge ist also:
Als Beispiel, sagen wir mal wir haben das Hauptprogramm (lpr Datei) mit Uses "Unit1, Unit2, Unit3". Unit1 nutzt Intern "Unit2, Unit1b", Unit2 nutzt "Unit2a, Unit2b" und Unit3 nutzt nichts. Dann ist der entsprechende Graph:
Code: Alles auswählen
Main.lpr
+----Unit1.pas
| +----Unit2.pas
| | +----Unit2a.pas
| | +----Unit2b.pas
| +----Unit1b.pas
+----Unit2.pas
| +----Unit2a.pas
| +----Unit2b.pas
+----Unit3.pasDanach ist Unit2.pas im Hauptprogramm dran, die wurde aber schon initialisiert, daher kann das übersprungen werden und Unit3.pas angefangen werden. Wenn die Fertig ist sind alle Dependencies von Main.lpr erfüllt und der Code kann ausgeführt werden.
Die letztendliche Reihenfolge ist also:
- Unit2a.pas
- Unit2b.pas
- Unit2.pas
- Unit1b.pas
- Unit1.pas
- Unit3.pas