AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Problem beim Beenden (DLL mit Formular und mODBC)
Thema durchsuchen
Ansicht
Themen-Optionen

Problem beim Beenden (DLL mit Formular und mODBC)

Offene Frage von "StTüff"
Ein Thema von StTüff · begonnen am 12. Sep 2007 · letzter Beitrag vom 4. Okt 2007
Antwort Antwort
Seite 3 von 3     123   
StTüff

Registriert seit: 3. Dez 2002
132 Beiträge
 
Delphi 2006 Enterprise
 
#21

Re: Problem beim Beenden (DLL mit Formular und mODBC)

  Alt 2. Okt 2007, 10:01
Hallo!

Ich habe jetzt noch folgendes herausgefunden:
Wenn ich das Formular so
Form1:=TForm1.Create(Application); oder so
Application.CreateForm(TForm1, Form1); erzeuge, dann wird beim schließen von Form1 nicht nur die DLL (bzw. das Form1) sondern auch die Anwendung, die die DLL aufgerufen hat beendet.
=> Offensichtlich steht in der Variablen "Application" die Referenz, auf das Programm, dass die DLL aufgerufen hat. Scheinbar verwenden die Komponenten (inklusive mODBC) dann dieses Application-Objekt. Das scheint ein grundsätzliches Problem zu sein. Ich gehe davon aus, dass es kein Problem geben würde, wenn die DLL ein eigenes Application-Objekt hätte.

Gibt es hier jemanden, der sich damit auskennt, oder soll ich einen separaten Thread in einer anderen Rubrik starten?

Gruß,

StTüff
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#22

Re: Problem beim Beenden (DLL mit Formular und mODBC)

  Alt 2. Okt 2007, 11:00
<offtopic>

Zitat von peschai:
Hallo
und bitte als guten stil verwende ich persönlich immer FreeAndNil und das als paar mit der abfrage auf Assigned.
Delphi-Quellcode:
if Assignd(Form1) then
  begin
    FreeAndNil(Form1)
  end;
Ähem! Nur FreeAndNil reicht: das prüft nämlich schon auf nil bzw. Assigned.
Weniger Zeilen machen dein Programm lesbarer!

</offtopic>
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#23

Re: Problem beim Beenden (DLL mit Formular und mODBC)

  Alt 2. Okt 2007, 11:10
Zitat:
Ähem! Nur FreeAndNil reicht: das prüft nämlich schon auf nil bzw. Assigned.
Weniger Zeilen machen dein Programm lesbarer!
Pustekuchen!
Dann schau dir mal den Source an (Delphi2007Prof) von SysUtils.pas:

Delphi-Quellcode:
procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;
Da ist keine Abfrage nach assigend!

Deshalb möglicher eigener Ersatz: (aber natürlich "langsamer")
Delphi-Quellcode:
procedure MyFreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  if assigned(Temp) then
    Temp.Free;
end;
Peter Schaible
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#24

Re: Problem beim Beenden (DLL mit Formular und mODBC)

  Alt 2. Okt 2007, 11:24
Zitat von peschai:
Da ist keine Abfrage nach assigend!
Stimmt ... die ist in der Methode TObject.Free
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
StTüff

Registriert seit: 3. Dez 2002
132 Beiträge
 
Delphi 2006 Enterprise
 
#25

Re: Problem beim Beenden (DLL mit Formular und mODBC)

  Alt 2. Okt 2007, 11:42
OK. Nach dem wir das geklärt haben noch mal zu meinem Problem:

Ich fasse zusammen:

- Beim Starten des Programms (das die DLL aufruft; statische Bindung) wird von mODBC der Initializeabschnitt ausgeführt (nicht beim create des Formulars).
- Der Finalizeabschnitt entsprechend beim Beenden und nich beim free des Formulars.
- Ist das Formular bereits freigegeben gibt es eine Exception (ungültiger Speicherzugriff). Wird das Formular nicht freigegeben gibt es kein Problem (abgesehen davon dass das Formular dann nicht freigegeben ist).
- Frage ich in der DLL "application.exename" ab so wird mir der Name der Aufrufenden Anwendung ausgegeben.
- Bei anderen Parametern (z.B. "application.mainForm") gibt es in der DLL eine Fehlermeldung in der EXE kann zugegriffen werden.
=> application ist also offensichtlich nicht identisch, hat aber Einfluss auf die Komponenten auf dem DLL-Formular (Verwendung von Application in mODBC).
- Gebe ich beim erzeugen des Formulars apllication als Parent an, so wird das Formular automatisch zerstört, die Fehlermeldung kommt aber trotzdem....

Alles schön zusammengefasst, aber immer noch keine Ahnung....

Kann das jemand nachvollziehen? Soll ich noch weitere Quellen (mODBC) oder sonst was hochladen?

Gruß und vielen Dank für die Unterstützung,

StTüff
  Mit Zitat antworten Zitat
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#26

Re: Problem beim Beenden (DLL mit Formular und mODBC)

  Alt 2. Okt 2007, 12:42
Hallo

@stTüff:
Hast du meine Absicherung mal eingebaut?
Sorry stTüff aber die Discussion mit Flocke ist auch für dich wichtig! Meiner Meinung nach kann hier Dir am schnellesten geholfen werden.

@Flocke:
Okay, Tobject.Free ist abgesichert, aber was ist mit den Nackommen?
In den meisten Fällen arbeiten wir mit Erben von TObject. Sobald diese etwas mehr im Free/Destroy
machen könnte in manchen Situation der Vorschlag von mir helfen. Denn da fehlt meistens die Assigned oder NIL-Abfrage... Ein Beispiel original Code:
Delphi-Quellcode:
destructor TCustomForm.Destroy;
begin
  Application.RemovePopupForm(Self);
  if not (csDestroying in ComponentState) then GlobalNameSpace.BeginWrite;
  try
    if OldCreateOrder then DoDestroy;
    MergeMenu(False);
    if HandleAllocated then DestroyWindowHandle;
    Screen.RemoveForm(Self);
    FCanvas.Free;
    FIcon.Free;
    FreeAndNil(FPopupChildren);
    FreeAndNil(FRecreateChildren);
    GlassFrame.Free;
    FreeMem(Pointer(FPixelsPerInch));
    inherited Destroy;
  finally
    GlobalNameSpace.EndWrite;
  end;
end;
Mein grundsätzlicher Vorschlag ist, daß es EXACT eine Variable gibt, welche den Zeiger auf ein dynamisch angelegtes Object oder Speicherbereich enthält. Wenn diese Variable einen Wert<>NIL beinhaltet, dann existiert das Object/Speicherbereich. Wenn diese Variable NIL beinhaltet, dann wurde es von mir auch wieder freigegeben! Natürlich kann es Kopien dieses Zeigers geben, aber es sollte immer klar sein, was ist die Referenz und was die Kopie.
Peter Schaible
  Mit Zitat antworten Zitat
StTüff

Registriert seit: 3. Dez 2002
132 Beiträge
 
Delphi 2006 Enterprise
 
#27

Re: Problem beim Beenden (DLL mit Formular und mODBC)

  Alt 2. Okt 2007, 14:23
Na klar habe ich die "Sicherung" eingebaut (war in meinem eigentlichen Projekt übrigens schon immer so, nur eben in dem vereinfachten Beispiel nicht).
Leider macht das keinen Unterschied. Es ist auch nicht so, dass der Fehler beim Destroy des Objektes auftritt. Vielmehr passiert beim finalize von mODBC irgendwas, was ich noch nicht näher eingrenzen konnte.

Momentan geht meine Vermutung wie oben erwähnt dahin, dass es etwas mit dem application-Objekt (bzw. mit den Unterschieden bei dem Objekt zwischen DLL und EXE) zu tun hat. Kann aber auch sein, dass ich da voll auf dem Holzweg bin. Sicher ist nur, dass nicht mehrfach versucht wird Form1 freizugeben. Allerdings ist ebenfalls sicher, wenn Form1 nicht freigegeben wird, tritt keine Fehlermeldung auf und Form1 wird definitiv nicht freigegeben (OnDestroy tritt dann nicht ein).

Ich komme einfach nicht so richtig weiter. Habe nur ich das Problem? Vermutlich ja: Sonst macht keiner was mit DLL und Forms, weil es da nur Probleme gibt, oder?

Vielleicht kann mir jemand eine Alternative nennen. Voraussetzung ist, dass der Aufruf der Funktione aus einer beliebigen Programmier-/Scriptsprache erfolgen kann (z.B. VBA).

Gruß,

StTüff
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#28

Re: Problem beim Beenden (DLL mit Formular und mODBC)

  Alt 2. Okt 2007, 15:01
@StTüff: Der Fehler tritt offensichtlich in TmSession.FreeHENV beim Aufruf von SQLFreeHandle auf. Da läuft offensichtlich irgendetwas schief, was du schlecht beeinflussen kannst. Als ganz bösen Workaround kannst du die Zeile "SQLFreeHandle" in TmSession.FreeHENV in try..except klammern und den Fehler ignorieren:
Delphi-Quellcode:
procedure TmSession.FreeHENV;
begin
  if FHENV = 0 then
    exit;
  try
    SQLFreeHandle(SQL_HANDLE_ENV, FHENV);
  except
  end;
  FHENV:=0;
end;
@peschai:
Zitat von peschai:
Okay, Tobject.Free ist abgesichert, aber was ist mit den Nackommen?
In den meisten Fällen arbeiten wir mit Erben von TObject. Sobald diese etwas mehr im Free/Destroy
machen könnte in manchen Situation der Vorschlag von mir helfen.
Man arbeitet in Delphi immer mit von TObject abgeleiteten Klassen. Hier gibt es für die Freigabe von Objekten zwei relevante Funktionen, die du ja schon genannt hast:

Den virtuellen Destruktor destructor Destroy,
1. den man in eigenen Klassen überschreiben kann,
2. der immer mit einem Aufruf von inherited; enden sollte und
3. den man nie direkt aufrufen sollte.

Die statische Methode procedure Free, die
1. man nie überschreiben sollte,
2. als einzige (letzendlich) nutzen sollte, um ein Objekt freizugeben und
3. die eben aus dem Grund existiert, dass sie prüfen kann ob "Self <> nil" ist - eine virtuelle Methode kann das nämlich nicht.

Darum reicht FreeAndNil! Den Zeiger vorher auf NIL zu prüfen ist überflüssig.
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
StTüff

Registriert seit: 3. Dez 2002
132 Beiträge
 
Delphi 2006 Enterprise
 
#29

Re: Problem beim Beenden (DLL mit Formular und mODBC)

  Alt 4. Okt 2007, 09:31
Hallo Flocke!

Danke für die Info! Da bin ich auf der einen Seite froh, dass ich nicht ganz auf dem Holzweg war, andererseits traurig, dass es keine "perfekte" Lösung gibt.

Die Frage, die jetzt noch bleibt: Ist es besser das Formular nicht freizugeben (Windows XP gibt den Speicher beim Beenden der Anwendung frei, oder?), oder eben den von Dir vorgeschlagenen Workaround zu verwenden.
Was hinterlässt potentiel mehr "Reste"?

Vielleicht findet auch noch jemand den genauen Grund. Ich werde mit meinen bescheidenen Mitteln auch noch mal forschen.

Gruß und noch mal vielen Dank,

StTüff
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:51 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