Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   DLL Einbindung - Fehler beim Beenden (https://www.delphipraxis.net/74325-dll-einbindung-fehler-beim-beenden.html)

fsc 1. Aug 2006 12:49


DLL Einbindung - Fehler beim Beenden
 
Moin!

Ich habe ein nettes kleines Tool geschrieben, womit man Einträge einer Tabelle ändern kann. --> Das funktioniert soweit.
Jetzt gibt es noch ein paar weitere Programme die ähnliche Aufgaben erfüllen. Der Sicherheit halber habe ich jede Tabelle mit den gleichen Feldern erweitert und frage diese dann per DLL ab und zeige sie an. Funktioniert bis dahin auch ganz wunderbar...

Wenn ich dann jedoch das Programm letztendlich beende (mit einem simplen "close"), kommt folgende Fehlermeldung: "Die Anweisung in xyz verweist auf Speicher in 123. Der Vorgang "read" konnte nicht auf dem Speicher ausgeführt werden." Danach kommt dann noch, "Runtime error 216 at xyz". Gestern habe ich das Internet bereits durchforstet nach Lösungen.

Meine CPU ist nicht zu schnell und ich habe auch keinen SubSeven auf dem Rechner. Hat jemand eine weitere Idee?

Sobald ich die Dll aus meinem Programm wieder entferne, geht alles wie vorher. Meine Frage lautet also: Was passiert eigentlich im Hintergrund wenn eine DLL aufgerufen wird? Innerhalb der DLL gebe ich alles was ich erzeugt habe auch wieder frei.

Vielen Dank im vorraus!

fsc

Luckie 1. Aug 2006 12:52

Re: DLL Einbindung - Fehler beim Beenden
 
Lädst du die DLL dynamisch?

fsc 1. Aug 2006 13:55

Re: DLL Einbindung - Fehler beim Beenden
 
nein sie ist statisch eingebunden. Es wird auch nur eine procedure aufgerufen, welche einer Datenbank Werte bzw Felder entnimmt und diese in ein StringGrid füllt.. dann modal anzeigt das wars

Robert Marquardt 1. Aug 2006 14:43

Re: DLL Einbindung - Fehler beim Beenden
 
Ist die DLL in Delphi geschrieben? Wurde ShareMem in DLL und Hauptprogramm verwendet?
Poste mal die Deklaratino der aufgerufenen Funktion.

fsc 1. Aug 2006 15:31

Re: DLL Einbindung - Fehler beim Beenden
 
die DLL habe ich mit Delhpi gemacht. ShareMem habe ich nicht verwendet.
Was macht ShareMem? :?:

Dekalration unter Implemtation steht:
...
procedure benutzer(Provider,feld,eintrag,einrag_detail:strin g)stdcall; external 'Aenderungsinfo.dll';

Robert Marquardt 2. Aug 2006 05:10

Re: DLL Einbindung - Fehler beim Beenden
 
Klassischer Fehler.
Sowohl in Hauptprogramm als auch DLL muss ShareMem eingebunden werden.
DLL und Hauptprogramm haben sonst separate Memorymanager.
Uebergibt und manipuliert man nun Strings oder Objekte (alles was dynamisch alloziiert ist), so wird Memory im einen Manager alloziiert und im anderen freigegeben.
Das Resultat ist dann schnell ein korrumpierter Memorymanager und irgendwann (oft beim Programmende) gibt es einen Absturz.
ShareMem verbindet beide Memorymanager so das es dann wieder einer ist.

Erzeuge mal ein leeres DLL-Projekt mit Delphi und lies dir durch was im Kommentar des erzeugten Files steht.

fsc 2. Aug 2006 09:09

Re: DLL Einbindung - Fehler beim Beenden
 
Danke erstmal!

Also ShareMem habe ich eingebunden..., einfach nur in die uses Liste, nicht wahr?

Jetzt erscheint beim schließen des aus der DLL heraus erzeugten Fensters eine Exception und beim Beenden einer dieser Windows Fehler: "Programm.exe hat einen Fehler verursacht" usw. Danach der Runtime error 217. Mit dem Datentyp ShortString und Pchar passiert das gleiche...

EDIT: Muss die DLL wirklich als erste Unit eingebunden werden oder ist das quatsch?!

TBx 2. Aug 2006 09:30

Re: DLL Einbindung - Fehler beim Beenden
 
jawoll, die muss unbedingt als erste eingebunden werden.

Gruß

onlinekater

fsc 2. Aug 2006 09:46

Re: DLL Einbindung - Fehler beim Beenden
 
das für zu einer Endlosschleife Exceptions nach beenden. erst 217 dann immer wieder 216.

TBx 2. Aug 2006 09:58

Re: DLL Einbindung - Fehler beim Beenden
 
poste doch mal Deinen Code, vielleicht können wir Dir dann helfen.

Definitiv muß sharemem sowohl im aufrufenden Projekt (nicht in dessen Mainform oder sonstwo) als auch in der DLL als erstes in die USES-Klausel aufgenommen werden.

Gruß

onlinekater

fsc 2. Aug 2006 10:28

Re: DLL Einbindung - Fehler beim Beenden
 
Delphi-Quellcode:
library Aenderungsinfo;
uses
  ShareMem,
  SysUtils,
  Dialogs,
  StdCtrls,
  Forms,
  Classes,
  Grids,
  kbmMemTable,
  uSOAPClient,
  QGraphics,
  Controls;

{$R *.res}

procedure benutzerdetails_anzeigen(provider,eindeutiges_feld,aktueller_eintrag,aktueller_eintrag_detail:string);stdcall; export;
var
  Form1:TForm;
  StrGr_Aenderung:TStringgrid;
  SoapManager:TSoapManager;
  SMT_Table:TSoapMemTable;
begin
  Form1:=TForm.Create(nil);
  Form1.Caption:='Datensatzdetails: '+aktueller_eintrag+' - '+aktueller_eintrag_detail;
  Form1.Position:=poScreenCenter;
  Form1.BorderStyle:=bsdialog;

  SoapManager:=TSoapManager.Create(nil);
  SoapManager.Active:=True;
  SMT_Table:=TSoapMemTable.Create(nil);
  SMT_Table.SOAPManager:=SoapManager;
  SMT_Table.ProviderName:=provider;
  SMT_Table.Active:=True;
  SMT_Table.Filtered:=True;
  SMT_Table.Filter:=eindeutiges_feld+'='''+aktueller_eintrag+'''';
  SMT_Table.Refresh;

  Form1.Height:=80;
  Form1.Width:=410;
  StrGr_Aenderung:=TStringgrid.Create(nil);
  with StrGr_Aenderung do
  begin
    Parent:=Form1;
    DefaultRowHeight:=20;
    Align:=alClient;
    if Form1.Height - Form1.ClientHeight > 28 then Form1.ClientHeight:=40 else Form1.ClientHeight:=45;//Form1.ClientHeight - (ClientHeight - Height);
    Form1.Width:=410;

    ColCount:=4;
    ColWidths[1]:=110;
    ColWidths[2]:=100;
    ColWidths[3]:=110;
    ColWidths[0]:=Width - ColWidths[1] - ColWidths[2] - ColWidths[3] - 7;
    RowCount:=2;
    FixedCols:=0;
    Cells[0,0]:=' Anlage von:';
    Cells[1,0]:=' Anlagedatum:';
    Cells[2,0]:=' Änderung von:';
    Cells[3,0]:=' Änderungsdatum:';
    Cells[0,1]:=SMT_Table.FieldbyName('benutzer_neu').asstring;  
    Cells[1,1]:=SMT_Table.FieldbyName('datum_neu').asstring;
    Cells[2,1]:=SMT_Table.FieldbyName('benutzer_aend').asstring;
    Cells[3,1]:=SMT_Table.FieldbyName('datum_aend').asstring;
    StrGr_Aenderung.Options:= [goFixedHorzLine, goFixedVertLine, goHorzLine, goVertLine];
    SMT_Table.Destroy;
    SoapManager.Destroy;
  end;
  try
    Form1.Update;
    Form1.ShowModal;
  finally
    Form1.Destroy;
   end;
end;

exports
  benutzerdetails_anzeigen;
Der Datenbankzugriff erfolgt über die SoapMemTable bzw SoapManager.

Im Hauptprogramm befindet sich ein ganz gewöhnlicher Prozedurenaufruf. Der Implementationteil steht bereits oben. Sharemem ist erster Eintrag in der uses Liste.

TBx 2. Aug 2006 10:55

Re: DLL Einbindung - Fehler beim Beenden
 
Hallo!

Du solltest Deine Objekte grundsätzlich nicht über Destroy sondern über Free zerstören. Free gibt nämlich auch den Speicher wieder frei.

Außerdem hast Du StrGr_Aenderung nicht zerstört.

Anbei nochmal Dein Code, mit Free. Ich habe außerdem das try-finally-Konstruct umgebaut, damit auch wirklich alles freigegeben wird.

Delphi-Quellcode:
library Aenderungsinfo;
uses
  ShareMem,
  SysUtils,
  Dialogs,
  StdCtrls,
  Forms,
  Classes,
  Grids,
  kbmMemTable,
  uSOAPClient,
  QGraphics,
  Controls;

{$R *.res}

procedure benutzerdetails_anzeigen(provider,eindeutiges_feld,aktueller_eintrag,aktueller_eintrag_detail:string);stdcall; export;
var
  Form1:TForm;
  StrGr_Aenderung:TStringgrid;
  SoapManager:TSoapManager;
  SMT_Table:TSoapMemTable;
begin
  Form1:=TForm.Create(nil);
  SoapManager:=TSoapManager.Create(nil);
  SMT_Table:=TSoapMemTable.Create(nil);
  StrGr_Aenderung:=TStringgrid.Create(nil);
  try
    Form1.Caption:='Datensatzdetails: '+aktueller_eintrag+' - '+aktueller_eintrag_detail;
    Form1.Position:=poScreenCenter;
    Form1.BorderStyle:=bsdialog;
    SoapManager.Active:=True;

    SMT_Table.SOAPManager:=SoapManager;
    SMT_Table.ProviderName:=provider;
    SMT_Table.Active:=True;
    SMT_Table.Filtered:=True;
    SMT_Table.Filter:=eindeutiges_feld+'='''+aktueller_eintrag+'''';
    SMT_Table.Refresh;

    Form1.Height:=80;
    Form1.Width:=410;

    with StrGr_Aenderung do
    begin
      Parent:=Form1;
      DefaultRowHeight:=20;
      Align:=alClient;
      if Form1.Height - Form1.ClientHeight > 28 then Form1.ClientHeight:=40 else Form1.ClientHeight:=45;//Form1.ClientHeight - (ClientHeight - Height);
      Form1.Width:=410;

      ColCount:=4;
      ColWidths[1]:=110;
      ColWidths[2]:=100;
      ColWidths[3]:=110;
      ColWidths[0]:=Width - ColWidths[1] - ColWidths[2] - ColWidths[3] - 7;
      RowCount:=2;
      FixedCols:=0;
      Cells[0,0]:=' Anlage von:';
      Cells[1,0]:=' Anlagedatum:';
      Cells[2,0]:=' Änderung von:';
      Cells[3,0]:=' Änderungsdatum:';
      Cells[0,1]:=SMT_Table.FieldbyName('benutzer_neu').asstring;
      Cells[1,1]:=SMT_Table.FieldbyName('datum_neu').asstring;
      Cells[2,1]:=SMT_Table.FieldbyName('benutzer_aend').asstring;
      Cells[3,1]:=SMT_Table.FieldbyName('datum_aend').asstring;
      StrGr_Aenderung.Options:= [goFixedHorzLine, goFixedVertLine, goHorzLine, goVertLine];
    end;
    Form1.Update;
    Form1.ShowModal;
  finally
    StrGr_Aenderung.Free; // fehlte ganz
    SMT_Table.Free;
    SoapManager.Free;
    Form1.Free;
   end;
end;

exports
  benutzerdetails_anzeigen;
Code ist ungetestet, da mir einige Units fehlen.

Hope it helps

onlinekater

fsc 2. Aug 2006 13:48

Re: DLL Einbindung - Fehler beim Beenden
 
situation unverändert...trotzdem super das du dir Zeit nimmst....

Robert Marquardt 3. Aug 2006 05:08

Re: DLL Einbindung - Fehler beim Beenden
 
Forms in DLLs geht ueblicherweise schief.

TBx 3. Aug 2006 08:05

Re: DLL Einbindung - Fehler beim Beenden
 
jetzt bleibt Dir eigentlich nur noch, auszuprobieren, welche der verwendeten Komponenten den Fehler verursacht.
Einfach eine nach der anderen auskommentieren und gucken, wann der Fehler sich verdünnisiert.

@Robert Marquardt: Habe eigentlich noch keine Probleme mit Forms in DLLs gehabt.

Gruß

onlinekater

fsc 4. Aug 2006 07:16

Re: DLL Einbindung - Fehler beim Beenden
 
habe die Komponenten nach und nach entfernt, es tut sich nichts, falls ich eine Lösung finde werde ich sie selbstverständlich posten...

ste_ett 4. Aug 2006 08:19

Re: DLL Einbindung - Fehler beim Beenden
 
Zeig mal den Code, mit dem du die Funktion aufrufst.
Evtl. hast du da einen Fehler gemacht (z.B. fehlendes stdcall). :)

fsc 6. Aug 2006 16:47

Re: DLL Einbindung - Fehler beim Beenden
 
Morgen poste ich den anderen Code. ich benutze allerdings stdcall, wie oben bereits zu sehen:

procedure benutzer(Provider,feld,eintrag,einrag_detail:strin g)stdcall; external 'Aenderungsinfo.dll';

Mir ist nochwas eingefallen: Ich benutze in der Funktion mit dem Aufruf einmal getmem, welchen ich am Ende allerdings wieder freigebe...


mfg

Mackhack 6. Aug 2006 19:57

Re: DLL Einbindung - Fehler beim Beenden
 
Zitat:

Zitat von Robert Marquardt
Forms in DLLs geht ueblicherweise schief.

Warum und was fuer Fehler meinst du denn da im Kongreten?

Elvis 6. Aug 2006 20:24

Re: DLL Einbindung - Fehler beim Beenden
 
Zitat:

Zitat von Mackhack
Zitat:

Zitat von Robert Marquardt
Forms in DLLs geht ueblicherweise schief.

Warum und was fuer Fehler meinst du denn da im Kongreten?

Weil die DLL eine eigene Kopie der VCL enthält.
Natürlich sind auch alle globalen Variablen der VCL doppelt im Speicher. Application aus der DLL ist nicht Application aus der Anwendung.
Für sowas gibt nimmt man Packages statt DLLs und Ruhe ist.
Möglich wäre es vllt auch in DLL und Exe die RTL & VCL als Runtime package anzugeben, aber da kommt wahrscheinlich immer noch Käse raus. (Habe ich noch nicht probiert)

Mackhack 6. Aug 2006 20:26

Re: DLL Einbindung - Fehler beim Beenden
 
Hm,

wir haben aber in unserem aktuellen Projekt Forms in dlls gepackt und die werden dynamisch aufgerufen und alles laeuft (seltsamerweise???) perfekt!

Elvis 6. Aug 2006 20:31

Re: DLL Einbindung - Fehler beim Beenden
 
Zitat:

Zitat von Mackhack
Hm,
wir haben aber in unserem aktuellen Projekt Forms in dlls gepackt und die werden dynamisch aufgerufen und alles laeuft (seltsamerweise???) perfekt!

Nicht jeder Käse stinkt gleich zum Himmel. ;-)
Solange die Forms nix mit der VCL der App zu tun haben und/oder mit der gleichen Delphi version gegen die gleichen VCL/RTL DCUs kompostiert wurden, kann ich mir gut vorstellen, dass es passt. (noch...)
Aber IMHO ist auch das Käse. Es macht einfach keinen (nada, niente, nüschts) Sinn, sich mit DLLs zu ärgern und Code zu duplizieren, wenn man nur Delphi mit Delphi reden lassen will.

Mackhack 6. Aug 2006 20:34

Re: DLL Einbindung - Fehler beim Beenden
 
Ja aber gibst du packages raus kann jeder das Ding schneller ansehen als du Hup sagen kannst!

Und ausserdem wollen wir halt eben verschiedene Versionen rausbringen und was nicht in der Exe steht ist nicht crackbar. Aber darueber haben sich schon viele gestritten!

Elvis 6. Aug 2006 20:42

Re: DLL Einbindung - Fehler beim Beenden
 
Zitat:

Zitat von Mackhack
Ja aber gibst du packages raus kann jeder das Ding schneller ansehen als du Hup sagen kannst!
Und ausserdem wollen wir halt eben verschiedene Versionen rausbringen und was nicht in der Exe steht ist nicht crackbar. Aber darueber haben sich schon viele gestritten!

Oh stümmt ja, ich vergaß, dass DLLs wunderamer Weise nicht crackbar sind, obwohl sie den gleichen PE Code enthalten... :gruebel:
Jetzt weiß ich auch, warum ich hier von Anfang an nicht antworten wollte und klinke mich vorsichtshalber gleich aus dem Thread raus. :hi:

Mackhack 6. Aug 2006 21:00

Re: DLL Einbindung - Fehler beim Beenden
 
Und warum so provokant nun?

Sagte ich irgendwas mit dlls sind uncrackbar? NEIN!

Ich sagte dass was nicht in der dll ist kann man auch nicht freischalten und somit ne Vollwertige Version erhalten. Richtig? Nicht mehr, nicht weniger!

Danke fuers Gespraech!

fsc 8. Aug 2006 06:38

Re: DLL Einbindung - Fehler beim Beenden
 
Ich bin gestern per Zufall auf die Lösung meines Problems gekommen. Bei einer Kollegin kam folgende Fehlermeldung: Anwendung konnte nicht gestartet werden, weil qtintf.dd nicht gewfunden wurde.. usw

In einem anderen Beitrag habe ich dann den Hinweis auf CLX Units gefunden...
Unbewusst hatte ich in die DLL eine dieser Q-Units eingebunden, nachdem ich diese entfernt hatte ging es...

Delphi-Quellcode:
uses
  ShareMem,
  SysUtils,
  Dialogs,
  StdCtrls,
  Forms,
  Classes,
  Grids,
  kbmMemTable,
  uSOAPClient,
  QGraphics, //<--- Diese Unit erzeugt den Fehler...
  Controls;
Vielen Dank für eure Hilfe!

mfg fsc

Christian Seehase 15. Sep 2006 20:59

Re: DLL Einbindung - Fehler beim Beenden
 
Moin Zusammen,

nur um noch mal etwas zum Runtime-Error 216 (sporadisch 217) hinzuzufügen:
Bei mir tritt das Ganze in einem D7-Projekt auf, nachdem ich in einer eingebundenen Unit eine Kleinigkeit geändert habe (es wurden ein paar Zeilen auskommentiert).
Es wird keine DLL eingebunden (ausser denen die implizit dazugehören versteht sich).

Diese Unit wird identisch in einem D2006-Projekt benutzt, und in diesem Falle tritt das Problem nicht auf (es werden auch die gleichen Funktionen benutzt).

Der Fehler tritt immer nach dem finalization-Abschnitt auf.

Starte ich das Programm aus der IDE heraus, und beende es, so erhalte ich einen "Zugriff verweigert".


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