Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   FreePascal (https://www.delphipraxis.net/74-freepascal/)
-   -   unit initialisieren (https://www.delphipraxis.net/151295-unit-initialisieren.html)

Berni68 11. Mai 2010 18:00


unit initialisieren
 
Hallo zusammen,

was fehlt in folgender Lazarus unit:
Delphi-Quellcode:
unit Unit2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Dialogs;

procedure init;
procedure test;

implementation

procedure test;
begin
  showmessage('Test');
end;
procedure init;
begin
  showmessage('init');
end;

initialization
begin
  init;
end;

end.
sobald ich irgendwas im Bereich initialization ausführe schrabbelt's, besser gesagt, es passiert nichts mehr, das Prog startet nicht mehr.
In delphi würde das gehen. Das Problem ist wohl, dass die unit dialogs zu diesem zeitpunkt
wo init ausgeführt wird noch nicht initialisiert ist. Aber wie kriegt man das hin?

uligerhardt 11. Mai 2010 18:39

Re: unit initialisieren
 
Das begin/end im initialization-Teil finde ich etwas schräg und würde
Delphi-Quellcode:
initialization
  init;
end.
vorziehen. Andererseits glaube ich nicht, dass sich der FPC davon ins Bockshorn jagen lässt und Müll generiert. :mrgreen:

Hier steht
Zitat:

Every unit can contain an initialization section. The order of the initialization sections depend on the uses sections of each unit.
Das kann man jetzt interpretieren, wie man will. Setzt doch einfach mal einen Breakpoint in die initialization-Sektion von Dialogs.pas und schau, ob der angeprungen wird.

Berni68 11. Mai 2010 18:46

Re: unit initialisieren
 
hab ich mit und ohne begin end ausprobiert und vieles andere mehr.
Das Ergebnis ist immer das gleiche: das Prog startet nicht.

Das einzige was in diesem Block geht sind Variableninitialisierungen
von variablen die in dieser Unit deklariert sind.
zugegeben, showmessage macht keinen Sinn,
aber as gleiche passiert wenn man z.B. eine TStrings Variable
erzeugt. Das ist wiederum praktisch um ini dateien zu lesen.
Aber alle Aufrufe von Prozeduren anderer Units scheitern.

Mich wundert dass man dazu nichts beim googlen findet.
Es ist doch nicht so unüblich ne unit zu initialisieren oder?
Gibt es ne andere Möglichkeit?

P.S.
Die Prozedur wird wird ausgeführt, hopst dann in diverse units
(je nachdem ob man Showmessage oder TStringlist.create oder... ausführt)
endet dann in einer exception class unknown
und dann muss ich Ctrl Alt Del bemühen und Lazarus abwürgen, sonst geht nichts mehr.

uligerhardt 11. Mai 2010 19:09

Re: unit initialisieren
 
Zitat:

Zitat von Berni68
endet dann in einer exception class unknown

Meinst du EClassNotFound? Steht irgendwo, welche Klasse unbekannt ist?

lbccaleb 11. Mai 2010 19:24

Re: unit initialisieren
 
Hast du die in deiner Unit verlinkten Units auch unter Uses der .dpr aufgeführt??
Wenn nicht mach das mal, und schaue ob es dann funktioniert!

Edit:
Aso, und Sie sollten dann vor der deiner Unit in der Liste aufgeführt werden.

Berni68 11. Mai 2010 19:32

Re: unit initialisieren
 
hab mal alle units in die .lpr aufgenommen -> gleiches Ergebnis. geht nicht

"exception: class unknown" mehr kommt nicht.

JamesTKirk 12. Mai 2010 15:42

Re: unit initialisieren
 
Hi!

Hast du in deinem Hauptprogramm (*.lpr) die Unit Interfaces aufgeführt (am besten als erstes)? Diese wird benötigt, um die Schnittstelle zum Widgetset (Win32 GDI, GTK2, QT, etc) zu initialisieren. Ohne sie kann der Zugriff auf die LCL (den du mit ShowMessage ja machst) nicht funktionieren.

Gruß,
Sven

shmia 12. Mai 2010 16:14

Re: unit initialisieren
 
Im Abschnitt initialization sollte man ganz vorsichtig sein.
Der Code wird so früh im Programm aufgerufen, dass viele Dinge noch nicht möglich sind.
ShowMessage() könnte durchaus dazu gehören.

Folgender Code müsste eigentlich laufen:
Delphi-Quellcode:
implementation
var
  start_message : string;

procedure test;
begin
  showmessage('Test -' + start_message);
end;
procedure init;
begin
  start_message := 'init ist erfolgt!'
end;

initialization
begin
  init;
end;
end.

jaenicke 12. Mai 2010 16:27

Re: unit initialisieren
 
Zitat:

Zitat von shmia
Der Code wird so früh im Programm aufgerufen, dass viele Dinge noch nicht möglich sind.
ShowMessage() könnte durchaus dazu gehören.

Was macht denn Lazarus da so anders als Delphi? :gruebel:

himitsu 12. Mai 2010 17:27

Re: unit initialisieren
 
Zitat:

Zitat von jaenicke
Was macht denn Lazarus da so anders als Delphi? :gruebel:

Ich dachte ja FPC (Lazarus) initialisiert auch alle im Interface gelinkten Units, bevor die Initialization ausgeführt wird ... also irgendwie macht mir das Angst. :shock:

shmia 12. Mai 2010 17:45

Re: unit initialisieren
 
Zitat:

Zitat von jaenicke
Was macht denn Lazarus da so anders als Delphi? :gruebel:

Weiss nicht so genau, aber eigentlich ist es auch egal.
Denn:
1.) es sind wahrscheinlich noch Initialization-Abschnitte anderer Units vorhanden, die noch nicht ausgeführt wurden
2.) die Reihenfolge in der die Initialization-Abschnitte ausgeführt werden lässt sich nicht zuverlässig und stabil bestimmen.
Man kann schon Einfluss nehmen über die Projektdatei aber das ist nicht zuverlässig;
man kann jederzeit aus Unachtsamkeit oder Unwissenheit die Reihenfolge ändern
3.) Application.Initialize wurde noch nicht aufgerufen


Daraus lassen sich folgende Schlüsse ziehen:
a.) man darf sich niemals darauf verlassen, dass andere Units schon initialisiert sind
b.) man darf im Initialization-Abschnitt nur Dinge tun, die keinerlei Nebenwirkungen haben
erlaubt wäre z.B. Zufallsgenerator mit Startwert belegen, Array mit Sinuswerten vorab berechnen
nicht erlaubt sind z.B. Aktionen, die in irgeneiner Art mit dem Benutzer in Kontakt treten
oder Code der potentiell eine Exception auslösen kann
c.) man sollte den Initialization-Abschnitt so gut wie möglich vermeiden, denn er kann nur mit globalen Variablen und globalen Resourcen arbeiten.

himitsu 12. Mai 2010 17:53

Re: unit initialisieren
 
Die Punkte 1 und 2 sind z.B. Delphi zwar auch "unberechenbar", aber es steht definitiv fest, daß alle Units, welche im Interface eingebunden werden immer vor der Initialization initialisiert werden.

Nur bei Units, welche erst in der Implementation eingebunden werden, ist diesbezüglich keine Garantie festgelegt.

Da Lazarus/FPC angeblich eine "Nachmache" von Delphi ist und dieses Verhalten schon immer so sein dürfte, sollte sich FPC doch auch daran halten?
Ansonsten würde ich dieses als gravierenden Fehler einstufen.




Also ich hoffe mal der Fehler liegt bei Punkt 3, denn auch in Lazarus dürfte ShowMessage ein VCL-Formular kapseln
und die VCL wird über Application.Initialize erst richtig initialisiert.

jaenicke 12. Mai 2010 18:29

Re: unit initialisieren
 
Application.Initialize wird normalerweise gar nicht gebraucht. Nur aus der Unit ComObj wird eine Initialisierungsmethode zum Beispiel eingetragen, das braucht man aber nur für COM. Rein mit der VCL hat das erst einmal nichts zu tun und man kann die Zeile (zumindest bei Delphi) einfach löschen.

himitsu 12. Mai 2010 20:14

Re: unit initialisieren
 
Daß darin in Delphi nichts passiert, weiß ich schon, aber ich könnte diesbezüglich nichts über Lazarus sagen.

Aber wenn es nicht Punkt 3 ist, dann .... nja :?

JamesTKirk 14. Mai 2010 14:58

Re: unit initialisieren
 
Zitat:

Zitat von jaenicke
Application.Initialize wird normalerweise gar nicht gebraucht. Nur aus der Unit ComObj wird eine Initialisierungsmethode zum Beispiel eingetragen, das braucht man aber nur für COM. Rein mit der VCL hat das erst einmal nichts zu tun und man kann die Zeile (zumindest bei Delphi) einfach löschen.

Ein kurzer Test durch Einfügen eines Application.Initialize vor dem init-Aufruf ergibt einen funktionierenden Dialog.
Ein kurzer Blick in das Application.Initialize ergibt, dass da durchaus einiges zum Start gemacht wird. Also eine LCL Anwendung am besten nie ohne diesen Aufruf starten. ;)

Ich würde auf jeden Fall aber nicht empfehlen LCL-Code innerhalb eines initialization-Abschnittes anzufassen (genause wie man es nicht von einem anderem Thread sollte). Das gibt nichts als Ärger.

EDIT: Rechtschreibung

Gruß,
Sven


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:53 Uhr.

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