Einzelnen Beitrag anzeigen

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