AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein TObject in DLL: Zugriffsverletzung beim Schließen
Thema durchsuchen
Ansicht
Themen-Optionen

TObject in DLL: Zugriffsverletzung beim Schließen

Ein Thema von hsg · begonnen am 23. Mär 2022 · letzter Beitrag vom 13. Apr 2022
Antwort Antwort
hsg

Registriert seit: 24. Apr 2006
Ort: Wustermark
354 Beiträge
 
Delphi 10.3 Rio
 
#1

TObject in DLL: Zugriffsverletzung beim Schließen

  Alt 23. Mär 2022, 14:42
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:
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;
Die beiden Methoden ConnectDB und DisConnectDB sowie die Klasse sehen wie folgt aus:
Delphi-Quellcode:
  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;
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.
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
  Mit Zitat antworten Zitat
Incocnito

Registriert seit: 28. Nov 2016
223 Beiträge
 
#2

AW: TObject in DLL: Zugriffsverletzung beim Schließen

  Alt 23. Mär 2022, 17:16
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:
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;
So zum Testen .. vielleicht reicht das ja schon.

LG Incocnito
  Mit Zitat antworten Zitat
BerndS

Registriert seit: 8. Mär 2006
Ort: Jüterbog
491 Beiträge
 
Delphi 12 Athens
 
#3

AW: TObject in DLL: Zugriffsverletzung beim Schließen

  Alt 23. Mär 2022, 20:04
Um Fehler bei der Freigabe zu vermeiden könntest du auch:
TdmPenta = class(TComonent) 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.
  Mit Zitat antworten Zitat
hsg

Registriert seit: 24. Apr 2006
Ort: Wustermark
354 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: TObject in DLL: Zugriffsverletzung beim Schließen

  Alt 24. Mär 2022, 06:12
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
  Mit Zitat antworten Zitat
Incocnito

Registriert seit: 28. Nov 2016
223 Beiträge
 
#5

AW: TObject in DLL: Zugriffsverletzung beim Schließen

  Alt 24. Mär 2022, 09:05
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
  Mit Zitat antworten Zitat
hsg

Registriert seit: 24. Apr 2006
Ort: Wustermark
354 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: TObject in DLL: Zugriffsverletzung beim Schließen

  Alt 24. Mär 2022, 10:08
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
Ja, habe ich auch. Das Testsystem ist bereits soweit wie möglich eingedampft, die anderen Objekte in der Klasse habe ich jetzt auch noch auskommentiert. Passiert dennoch.
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
675 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: TObject in DLL: Zugriffsverletzung beim Schließen

  Alt 24. Mär 2022, 11:11
Häng Dich doch mal in die FreeNotification des session objects um zu schauen, ob diese irgendwie vorher freigegeben wird.
  Mit Zitat antworten Zitat
Incocnito

Registriert seit: 28. Nov 2016
223 Beiträge
 
#8

AW: TObject in DLL: Zugriffsverletzung beim Schließen

  Alt 24. Mär 2022, 16:44
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:
...Wird die Problemstelle auskommentiert, beendet sich das Programm ohne jeglichen Fehler. ...
Never mind!

LG Incocnito

Geändert von Incocnito (24. Mär 2022 um 16:48 Uhr)
  Mit Zitat antworten Zitat
hsg

Registriert seit: 24. Apr 2006
Ort: Wustermark
354 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: TObject in DLL: Zugriffsverletzung beim Schließen

  Alt 13. Apr 2022, 14:49
Häng Dich doch mal in die FreeNotification des session objects um zu schauen, ob diese irgendwie vorher freigegeben wird.
Moin,
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.

Edit:
...Wird die Problemstelle auskommentiert, beendet sich das Programm ohne jeglichen Fehler. ...
Never mind!

LG Incocnito
Zumindest wird mir kein Fehler angezeigt, im Gegensatz im Fall des ordnungsgemäßen Aufräumens.
  Mit Zitat antworten Zitat
Antwort Antwort


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 14:12 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