Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Problem beim Beenden (DLL mit Formular und mODBC) (https://www.delphipraxis.net/99441-problem-beim-beenden-dll-mit-formular-und-modbc.html)

StTüff 12. Sep 2007 10:22


Problem beim Beenden (DLL mit Formular und mODBC)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen!

Ich poste diesen Thread in "Sonstige Fragen zu Delphi", weil ich mir nicht ganz sicher bin, wo das Thema einzuordnen ist.

Ich möchte eine DLL erstellen, die mir Daten aus einer Datenbank (die nur per ODBC erreicht werden kann) aufbereitet und zur Verfügung stellt. Die DLL wird später dann in Verbindung mit diversen Scriptsprachen verwendet. Für den Datenzugriff verwende ich mODBC. Da der Anwender noch einige Einstellungen vornehmen muss, verwende ich in der DLL auch ein VCL-Formular, auf dem auch die Datenbankzugriffskomponenten platziert sind.

Um es etwas klarer zu machen, habe ich gleich ein Beispielprojekt angehängt.
Es beinhaltet den Quellcode der DLL + eine Exe-Datei, welche die exportierte Funktion aufruft (nach einem Click auf den Button). Als Datenquelle kann zum Testen eine beliebige ODBC-Datenquelle verwendet werden.

Das Problem entsteht erst beim Beenden. Wenn ich Form1.free aufrufe gibt es eine Speicherschutzverletzung und es wird ein Runtime-Error angezeigt. Verzichte ich auf das free, so erhalte ich keine Fehlermeldung, das Formular wird dann aber auch nicht korrekt freigegeben.

Ich vermute, dass es mit der Reihenfolge zu tun hat in der die einzelnen Bestandteile freigegeben werden. Mir ist aber weder klar, wie ich das herausfinden, noch wie ich das lösen/beeinflussen kann.

Ich habe schon versucht dass Fromular zu verschiedenen Zeitpunkten frei zu geben: ohne Erfolg.

Vielleicht hat jemand eine Idee dazu....

Gruß und schon mal vielen Dank,

StTüff

StTüff 18. Sep 2007 14:12

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

Hat sich das schon mal jemand angeschaut? Ich wäre auch an der Info interessiert, wenn das Problem nicht nachvollzogen werden konnte. Vielleicht ist es ja ein spezielles Problem an meinem Rechner? Ich glaube aber eher, dass ich einen kleinen aber entscheidenden Fehler gemacht habe (mal wieder).

Gruß,

Stüff

StTüff 1. Okt 2007 13:08

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

Hat keiner 'ne Idee, Anregung, einen Link, oder eine Hinweis?
Momentan komme ich an der Stelle einfach nicht weiter. Ich implementiere nach und nach alle Funktionen in der DLL und hoffe, das es eine Lösung gibt. Wenn nicht bzw. wenn ich einen grundlegenden Fehler gemacht habe, sehe ich dann alt aus.

Ich bin also auch dankbar, wenn mich jemand darauf hinweist, dass ich einen Anfängerfehler gemacht habe... :roll:

Gruß,

StTüff

blauweiss 1. Okt 2007 13:21

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
hi StTüff,

habe mir Dein Projekt nicht genauer angeschaut, aber ich hatte ähnliche Probleme mit Formularen in DLLs.
Bis ich herausgefunden habe, daß DLL-Formulare geschlossen sein müssen beim Entladen der DLL !

Habe also einfach eine Procedure exportiert "CloseAllForms" oder so, welche alle DLL-Formulare schließt. Diese Procedure rufe ich auf beim Programmende vor Entladen der DLL.

Hoffentlich hilft's ?!

Gruß
blauweiss

StTüff 1. Okt 2007 13:36

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

Danke für die Nachricht!
Ich werde mir das noch mal genau anschauen. Ich meine aber dass das so ist. Das Problem scheint zu sein, dass der finalize-Abschnitt der mODBC-Komponente erst abgearbeitet wird, nachdem ich das Formular mit free freigegeben habe. Dann "crashts" natürlich. Lasse ich das "free" weg, so gibt es keine Fehlermeldung, aber eigentlich sollte man das Formular, dass man erzeugt hat doch auch wieder freigeben.... (macht zwar unter XP - so glaube ich - nicht viel aus, aber sauber ist das nicht).

Mir sind jetzt 2 Dinge nicht ganz klar:
1. Wann wird der finalize-Abschnitt aufgerufen (im Vergleich DLL zu exe).
2. Wie kann die Reihenfolge festgelegt werden bzw. wie kann ich die Formulare nach dem Ablauf des finalize-Abschnitts freigeben.

Viellecht komme ich über diese Fragen zu einer möglichen Lösung :coder2:

Gruß und besten Dank,

StTüff

blauweiss 1. Okt 2007 16:58

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
hallo StTüff,

habe mir Dein Projekt mal auf die Schnelle angeschaut, und mir ist aufgefallen, daß Du offenbar eben gerade NICHT das Formular schließst. Die exportierte Prozedur FreeDLL gibt das nicht-modale Formular nur frei, schließt es aber zuvor nicht !

Crasht es immer noch, wenn Du das DLL-Formular zur Laufzeit schließst, und dann erst das Hauptprogramm beendest ?

Gruss
blauweiss

StTüff 2. Okt 2007 06:08

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

Es ist richtig, dass dies im Programmcode nicht zu finden ist. Ich habe das Formular aber bisher immer geschlossen (mit X), bevor ich das aufrufende Programm beendet hatte. Zur Sicherheit habe ich jetzt vor dem "free" noch Form1.close eingefügt => keine Änderung.

Hast Du das Programm nur angeschaut, oder auch mal getestet? Tritt der Fehler bei Dir auch auf?

Gruß,

StTüff.

peschai 2. Okt 2007 06:20

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

Grundsätzlich sollte man immer nur die Türen auch schliessen, welche man selber geöffnet hat und auch nur diese. Das soll heißen, daß du Form1.Free eventuell nicht aufrufen solltest, da dass Aufräumen der Forms normalerweise automatisch passiert. Wenn du es allerdings selber "Created" hast, dann OK.

Desweitern sollte in einer DLLAufräumRoutine auch nur das aufgeräumt werden, was in der DLL erzeugt wurde. Denke hier in Zonen, welche sich selber unabhängig verwalten.

Du solltest auch immer in der umgekehrten Reihenfolge aufräumen (FirstIn-LastOut)

Desweiteren sollte man anstelle
Delphi-Quellcode:
MyObject.Free;
besser verwenden
Delphi-Quellcode:
FreeAndNil(MyObject);
, Denn dabei wird die Variable MyObject auf NIL gesetzt. Das kannst du dann nutzen, indem du in deinen Methoden/Funktionen prüfst, ob das Object noch da ist, also eventuell in Finalization
Delphi-Quellcode:
If Assigned(MyObject)then

StTüff 2. Okt 2007 06:35

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

Danke für Deine Nachricht!
Leider möchte ich es eigentlich genau so machen, wie Du vorschlägst: Ich erzeuge das Formular und möchte es dann auch wieder freigeben. Leider ist es aber so, dass ich keinen Einfluss daruf habe, wann der finalize-Abschnitt der mODBC-Komponente aufgerufen wird (das mache ich nämlich nicht selbst). Ich gebe das Formular zum (mir) letzt möglichen Zeitpunkt (nämlich beim entladen der DLL) frei. Ich kann aber mit dem Debugger sehen, dass der Finalize-Abschnitt danach aufgerufen wird und es dann (logischer weise) zu dem Fehler kommt.
Genau das ist der Punkt, den ich 1. nicht verstehe und 2. keine Ahnung habe, wie ich das verhindern kann.

Warum wird der Finalize-Abschnitt erst nach dem Free des Formulars aufgerufen?
Wie kann ich dafür sorgen, dass erst der Finalize-Abschnitt aufgerufen wird und dann das Formular freigegeben wird?

Ich denke das sind die entscheidenden Fragen (wenn ich nicht noch was anderes komplett falsch gemach habe, was durchaus möglich ist).

Gruß und noch mal vielen Dank!

StTüff

PS: FreeAndNil bring in diesem Fall leider keine Abhilfe, auch wenn ich Dir ansosnten natürlich diesbezüglich recht gebe.

peschai 2. Okt 2007 06:36

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

Zusatzanmerkungen:
Zitat:

Delphi-Quellcode:
procedure DLLMain(Reason: Integer);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      begin
       DisableThreadLibraryCalls(hInstance);
       //CoInitialize(nil);
       
      end;
    DLL_THREAD_ATTACH:
        ;
    DLL_THREAD_DETACH:
      ;
    DLL_PROCESS_DETACH:
      begin
       //CoUnInitialize;
      // Form1.Free();
      end;
  end;

  if Assigned(DLLProcNext) then DLLProcNext(Reason);
end;

exports
  StartReport, FreeDLL;

begin
  DLLProcNext := Pointer(InterlockedExchange(Integer(@DLLProc), Integer(@DLLMain)));
  DLLMain(DLL_PROCESS_ATTACH);
end.

Kann es sein, daß du dynamisch DLL's laden und entladen hier vermischt mit statischem Laden Entladen ? Ich komme zu dieser Frage wegen deiner BEGIN section und dem exports FreeDLL.
Wenn Statisch, (also programstart, dann dll auto geladen und bei Programmende auto entladen)
dann würde ich dir empfehlen:
Delphi-Quellcode:
exports
  StartReport;
Initialization
  DLLMain(DLL_PROCESS_ATTACH);
  ...DLLProcNext...
Finalization
  ...DLLProcNext...
  DLLMain(DLL_PROCESS_DETACH);
end;

peschai 2. Okt 2007 06:42

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
Hallo
unsere Antworten haben sich überschnitten ...

Eventuell hilft dir punktuell
Delphi-Quellcode:
if Assignd(Form1) then
  begin
    FreeAndNil(Form1)
  end;
..Aber in deiner Programmgesamtlogic stimmt noch etwas nicht:
Für die Freigabe ist normalerweise der Owner zuständig...und eventuell passiert das bereist und du bekommet deshalb den Absturz...

Wo und wie erzeugst du dass Formular ?

StTüff 2. Okt 2007 06:43

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

Ich kann doch jetzt noch nicht wissen, wie die DLL verwendet wird. Bei meinem Beispielprojekt macht es keinen Unterschied, ob die DLL dynamisch, oder statisch geladen wird.
"DLL_PROCESS_ATTACH" wird immer beim laden der DLL (egal ob staisch, oder dynamisch) aufegerufen und "DLL_PROCESS_DETACH" immer beim entladen.
Vielleicht habe ich aber auch Deine Bemerkung nicht richtig verstanden.

Gruß,

StTüff

StTüff 2. Okt 2007 06:47

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

Aktueller Stand:
Delphi-Quellcode:
procedure DLLMain(Reason: Integer);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      begin
       DisableThreadLibraryCalls(hInstance);
       Form1:=TForm1.Create(nil);
      end;
    DLL_THREAD_ATTACH:
        ;
    DLL_THREAD_DETACH:
      ;
    DLL_PROCESS_DETACH:
      begin
       FreeAndNil(Form1);
       //Problem bei mSession finalization         !!!!!!!!!!!1
      end;
  end;
Beim Laden erzeugen, beim entladen freigeben.

Gruß,

StTüff

Edit:
Im ursprünglichen Beispiel:
Delphi-Quellcode:
initialization
begin
  Form1:=TForm1.Create(nil);
end;

finalization
begin
  Form1.Free;
end;
In der Datei DataMain.pas.... Macht aber keinen Unterschied.

peschai 2. Okt 2007 06:58

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

Weitere zusatzinfo:

Per defintion wird die Finalization section als letztes aufgerufen, quasi beim entladen des Moduls.
Das kann nicht geändert werden und das darf auch nicht geändert werden.

peschai 2. Okt 2007 07:03

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
Hallo
du gibst Form1 an zwei stellen frei ohne vorherige Prüfung mit Assigned!

StTüff 2. Okt 2007 07:05

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

Zitat:

Für die Freigabe ist normalerweise der Owner zuständig...und eventuell passiert das bereist und du bekommet deshalb den Absturz...
Da mODBC eine Komponente ist, die auf dem Formular platziert wurde, gehe ich davon aus, dass der Owner das Formular ist. Das Formular wiederum hat keinen Owner, da ich dieses selbst erzeuge und freigebe.
Ich wäre jetzt davon ausgegangen, dass beim zerstören des Formulars das Modul entladen wird. Offensichtlich geschieht das aber erst später (abhängig von was?).

Sollte ich beim Erzeugen des Formulars vielleicht einen Owner angeben? Aber welchen?

Gruß und vielen Dank für die Hilfe!

StTüff

PS: In meinem aktuellen Projekt gibt es nur 1 mal "free" bzw. FreeAndNil und ich glaube im Beispiel alleine auch nicht mehrmals. Ich hatte in der Nachricht nur zwei verschiedene Möglichkeiten genannt, deshalb sieht es vielleicht so aus....

peschai 2. Okt 2007 07:24

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

Zitat:

Ich wäre jetzt davon ausgegangen, dass beim zerstören des Formulars das Modul entladen wird. Offensichtlich geschieht das aber erst später (abhängig von was?).
Das Freigeben bzw. beenden des Formulars hat nichts mit dem entladen des Moduls zu tun.
Das Entladen des Moduls (DLL) passiert immer als letztes!

Beim statischen Linken von Dll's werden diese vom Betriebssystem automatisch bei Programmstart geladen und beim Beenden des Programms (.exe) wieder entladen. Das hier ist meiner Meinung nach auch das richtige für dich.

Beim dynamische Linken schreibst du Code, der die DLL lädt und must dementsprechend auch wieder Code schreiben zum Entladen (stichwort LoadLibrary, DLLReferenzZähler sollte dir hier etwas sagen, sonst bitte nachlesen)

peschai 2. Okt 2007 07:36

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
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;

StTüff 2. Okt 2007 07:41

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

Das erklärt zwar auf der einen Seite das Verhalten, dass der Fehler erst beim Beenden des Aufrufenden Programms auftritt, die Frage ist aber, was kann ich tun um das Problem zu beseitigen.
Wie im letzten Besipiel gezeigt, versuceh ich das Fromular erst beim Entladen freizugeben. Offensichtlich (wie Du ja auch geschrieben hast) ist das entladen des Moduls immer das letzte.

Damit habe ich 2 neue Fragen:
1. Warum passiert das nicht wenn ich mODBC in einer normalen GUI Anwendung (EXE) verwende.
2. Ist das dann ein Fehler in mODBC?

Gruß,

StTüff

StTüff 2. Okt 2007 08:32

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

Ich habe mir mal den Quellcode angeschaut. Eventuell ist es ein grundsätzliches Problem, dass es kein Application-Objekt gibt?!
Im Quellcode von mODBC taucht immer mal wieder "Application." auf.

Kann da jemand was dazu sagen?

Gruß,

StTüff

StTüff 2. Okt 2007 10:01

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

Ich habe jetzt noch folgendes herausgefunden:
Wenn ich das Formular so
Delphi-Quellcode:
Form1:=TForm1.Create(Application);
oder so
Delphi-Quellcode:
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

Flocke 2. Okt 2007 11:00

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

Zitat:

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>

peschai 2. Okt 2007 11:10

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
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! :angel:

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;

Flocke 2. Okt 2007 11:24

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

Zitat von peschai
Da ist keine Abfrage nach assigend! :angel:

Stimmt ... die ist in der Methode TObject.Free :P

StTüff 2. Okt 2007 11:42

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
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.... :pale:

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

peschai 2. Okt 2007 12:42

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
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? :twisted:
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.

StTüff 2. Okt 2007 14:23

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
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

Flocke 2. Okt 2007 15:01

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
@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:

Zitat von peschai
Okay, Tobject.Free ist abgesichert, aber was ist mit den Nackommen? :twisted:
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.

StTüff 4. Okt 2007 09:31

Re: Problem beim Beenden (DLL mit Formular und mODBC)
 
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


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:21 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