![]() |
TObject in DLL: Zugriffsverletzung beim Schließen
Moin,
ich habe eine DLL geschrieben, auf die gleichzeitig von Delphi- und VBA-Programmen zugegriffen wird. Der Zugriff geschieht dabei grundsätzlich über exportierte Funktionen und Prozeduren. Innerhalb dieser DLL habe ich eine Klasse von TObject abgeleitet, die für die Datenbankzugriffe zuständig ist. Dafür sind zwei Prozeduren zuständig: eine für die Anmeldung an der Datenbank, die andere für die Abmeldung.
Delphi-Quellcode:
Die beiden Methoden ConnectDB und DisConnectDB sowie die Klasse sehen wie folgt aus:
procedure ConnectDB(cPServer, cPUser : PAnsiChar); stdcall;
var cServer: AnsiString; cDBUser : AnsiString; begin cServer := AnsiString(cPServer); cDBUser := AnsiString(cPUser); try if not Assigned(dmDLLPenta) then begin dmDLLPenta := TdmPenta.Create(); end; dmDLLPenta.ConnectDB(String(cServer), String(cDBUser)); except on E : Exception do begin Warning('Fehler bei Verbindungsaufbau: ' + E.Message); end; end; end; procedure DisConnectDB( ); stdcall; begin if Assigned(dmDLLPenta) then begin dmDLLPenta.DisConnectDB(); FreeAndNil(dmDLLPenta); end; end;
Delphi-Quellcode:
In den Delphi-Programmen habe ich jetzt das Problem, dass beim Beenden des Programmes im Debugger eine Exception (Access Violation at adress ....) am Ende der DLL-Freigabe geworfen wird, die im Aufrufstack bei System.Halt() anfängt und irgendwo weiter oben tatsächlich auch Adressen im Oracle-Client aufweist.
TdmPenta = class(TObject)
private oPS : TPentaSettings; cDBUser : String; oPenta : TPenta; public osnPenta : TOraSession; qryAbf : TOraQuery; constructor Create(); reintroduce; destructor Destroy(); override; procedure ConnectDB(cServer, cUser : String); procedure DisConnectDB(); end; constructor TdmPenta.Create(); begin inherited; oPenta := TPenta.Create(); oPS := TPentaSettings.Create(); osnPenta := TOraSession.Create(nil); qryAbf := TOraQuery.Create(nil); qryAbf.Session := osnPenta; end; destructor TdmPenta.Destroy; begin try FreeAndNil(qryAbf); FreeAndNil(osnPenta); // <==== Problemstelle FreeAndNil(oPS); if Assigned(oPenta) then begin FreeAndNil(oPenta); end; except on E : Exception do begin dbg('FSGVBA - Destroy Fehler aufgetreten: ' + E.Message); end; end; inherited; end; procedure TdmPenta.ConnectDB(cServer, cUser: String); begin if not Assigned(oPenta) then begin oPenta := TPenta.Create(); end; if not Assigned(osnPenta) then begin osnPenta := TOraSession.Create(nil); end; if not Assigned(qryAbf) then begin qryAbf := TOraQuery.Create(nil); qryAbf.Session := osnPenta; end; DBUser := cUser; osnPenta.Server := cServer; osnPenta.Username := cUser; osnPenta.Password := 'xxxx'; Settings.GetSettings(cUser); osnPenta.Connected := true; if Assigned(oPenta) then begin oPenta.DBSession := osnPenta; end; end; Wird die Problemstelle auskommentiert, beendet sich das Programm ohne jeglichen Fehler. Es ist keine Exception zu sehen, wenn das Programm ohne Debugger gestartet wird! Die Datenbankconnection wird in beiden Fällen trotzdem geschlossen. 1) Sowohl Create als auch Destroy der dmDLLPenta werden nur 1x aufgerufen! 2) Die Session ist während des Programmlaufs vollkommen i.O. Datenbankabfragen werden ohne jegliche Probleme ausgeführt. Der Ärger fängt erst an, wenn das Programm (im Debugger!) geschlossen wird. 3) Ich habe u.a. auch eine DllProc hinterlegt, die mir den DLL_PROCESS_DETACH meldet. Diese Meldung kommt vor der Exception 4) Verwendet werden die ODAC-Komponenten von Devart in Version 11.1.3 für Delphi 10.3 und 12.0.2 für Delphi 11.0, es passiert dasselbe in beiden Versionen. Ich bin inzwischen ziemlich ratlos, was da schief geht. Irgendjemand Hinweise? Gruß hsg |
AW: TObject in DLL: Zugriffsverletzung beim Schließen
Moin,
ohne Ahnung von irgendwas ... In constructor TdmPenta.Create(); setzzt du die Eigenschaft "Session" von "qryAbf". In Destroy gibt du erst das komplette "qryAbf" frei und dann das Objekt, was du in der Eigenschaft "Session" hinterlegt hattest. Vielleciht gibt qryAbf das schon selbst frei. Setze das vorher mal auf "nil":
Delphi-Quellcode:
So zum Testen .. vielleicht reicht das ja schon.
destructor TdmPenta.Destroy;
begin try qryAbf.Session := nil; // <- Test FreeAndNil(qryAbf); FreeAndNil(osnPenta); // <==== Problemstelle FreeAndNil(oPS); if Assigned(oPenta) then begin FreeAndNil(oPenta); end; except on E : Exception do begin dbg('FSGVBA - Destroy Fehler aufgetreten: ' + E.Message); end; end; inherited; end; LG Incocnito |
AW: TObject in DLL: Zugriffsverletzung beim Schließen
Um Fehler bei der Freigabe zu vermeiden könntest du auch:
Delphi-Quellcode:
verwenden. Dadurch wäre es möglich den im Create erzeugten DB Komponenten als Owner Self zu übergeben. Eine Freigabe im destroy wäre damit überflüssig.
TdmPenta = class(TComonent)
|
AW: TObject in DLL: Zugriffsverletzung beim Schließen
Moin,
habe jetzt mal die Session-Property im qryAbf auf nil gesetzt, hat aber leider nichts geändert. Das die Klasse inzwischen von TObject abgeleitet ist, ist einer der zahlreichen Versuche, die ich inzwischen gemacht habe. Es war zuvor tatsächlich sogar ein ganz normales TDataModul und die Zerstörung der Objecte lagen in der Hand des normalen Zerstörungsprozesses von Delphi. Dort trat das Phänomen also zuerst auf. Gruß hsg |
AW: TObject in DLL: Zugriffsverletzung beim Schließen
Hmmm ... hast du das Problem auch, wenn du nicht Connect(); aufrufst?
Ansonsten mal dein Test-Programm weiter kürzen. Das hilft meist einen besseren Überblick zu haben. Vielleicht sehen die Kollegen hier dann auch den Fehler schneller. 😅 LG Incocnito |
AW: TObject in DLL: Zugriffsverletzung beim Schließen
Zitat:
|
AW: TObject in DLL: Zugriffsverletzung beim Schließen
Häng Dich doch mal in die FreeNotification des session objects um zu schauen, ob diese irgendwie vorher freigegeben wird.
|
AW: TObject in DLL: Zugriffsverletzung beim Schließen
Ich weiß ja nicht, wie TOraQuery definiert ist, wir haben das hier nicht.
Wenn die beim Setzen des Property "Session" sich das Objekt einfach speichern (oder anderweitig weiter leiten) und das dann darüber freigegeben wird, obwohl du noch das Property "Session" auf nil setzt hast du eh verloren. Ansonsten mal osnPenta nicht freigeben (nur auf nil setzen) und schauen, ob es ein Speicherleck gibt (ReportMemoryLeaksOnShutdown auf True). Wäre vielleicht noch interessant. Edit: Zitat:
LG Incocnito |
AW: TObject in DLL: Zugriffsverletzung beim Schließen
Zitat:
sorry, dass ich erst jetzt mich melde, aber ich war in den letzten Wochen leider gesundheitlich aus dem Verkehr gezogen. Ich habe jetzt mal eine Klasse TMyOraSession um die TOraSession geschrieben und mir angesehen, wann das Destroy aufgerufen wird. Das Destroy wird nur an der gewünschten Stelle ausgelöst. Trotzdem kommt nach wie vor die Exception. Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:48 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