Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Fehlerbehandlung bei dll (https://www.delphipraxis.net/208455-fehlerbehandlung-bei-dll.html)

nezumi7 31. Jul 2021 07:21

Fehlerbehandlung bei dll
 
Liebe Profis,

ich habe vor Jahren einmal in Delphi6 ein Programm geschrieben, das mir meine Kontobuchungen ordnet (schlichtes Auswerten von Textdateien). Dabei war vorgesehen, dass in ein paar wenigen Fällen ein Wechselkurs aus dem Internet abgerufen wird.

Mittlerweile funktioniert letzteres nicht mehr, weil es kaum noch ungesicherte Internetseiten gibt und Delphi6 und https nicht geht oder zumindest recht mühsam ist.

Ich habe daher den Internetaufruf in einer brandaktuellen Delphi-Version geschrieben und in eine dll gepackt, die dann von meinem Delphi6-Programm verwendet wird:

dll:
Delphi-Quellcode:
library internet;

uses
  System.SysUtils,
  System.Classes,
  System.Net.URLClient,
  System.Net.HttpClient,
  System.Net.HttpClientComponent;

{$R *.res}

function get_course(url: ShortString): shortstring; stdcall;
var
  HttpClient: THttpClient;
  HttpResponse: IHttpResponse;
 begin
Result := '';

HttpClient := THTTPClient.Create;
  try
    HttpResponse := HttpClient.Get(url);
    vtext := HttpResponse.ContentAsString();
  finally
    HttpClient.Free;
  end;

{es folgt eine längere Auswertung des Seitenquelltextes, der Kurs wird dann ins Result geschrieben. Hier liegt nicht das Problem} 
  end;

exports
  get_course;
begin
end.

Host:
Delphi-Quellcode:
implementation

{$R *.dfm}

function get_course(url: ShortString): Shortstring; stdcall; external 'internet.dll';

procedure TForm1.Button1Click(Sender: TObject);
begin

Edit2.Text := get_course(Edit1.text);

end;
Klappt alles wunderbar, das Problem ist nur: wenn die Internetverbindung unterbrochen ist, geht gar nichts mehr, das ganze Programm hängt sich total auf, trotz try/ error beim Aufruf.

Für mich ist dll völlig neu, offenbar gelten hier andere Regeln beim Fehlerhandling. Hat jemand eine Idee, wie man das machen kann? (Quick and dirty würde vollkommen reichen. Ich brauche keine Fehlermeldung, es reicht, wenn die Funktion bei einem Fehler einfach gar nichts zurück gibt. Wichtig ist mir nur, dass sich bei Problemen mit der Internetverbindung nicht alles aufhängt.....

jaenicke 31. Jul 2021 09:41

AW: Fehlerbehandlung bei dll
 
Du kannst in Delphi 6 soweit ich das sehe auch noch die aktuellste Indy-Version verwenden, zumindest gibt es dort im Lib-Verzeichnis noch eine Batchdatei dafür:
https://github.com/IndySockets/Indy/tree/master/Lib

Und zu den Fehler:
Das funktioniert bei mir problemlos. Wie hast du den Fehler denn abgefangen? Bei mir landet die DLL (wie es sein soll) im try..except und gibt einen Leerstring zurück.

Der schöne Günther 31. Jul 2021 11:15

AW: Fehlerbehandlung bei dll
 
Ich sehe nirgendwo ein
Delphi-Quellcode:
try..except
. Das sollte in deiner DLL sein damit die Exception die DLL nicht verlässt.
Kannst du die entsprechende Stelle mal zeigen?

himitsu 31. Jul 2021 12:56

AW: Fehlerbehandlung bei dll
 
Das Einzige, wo eine Delphi-Exception die DLL verlassen darf, ist, wenn die aufrufende EXE/DLL "ebenfalls" mit Laufzeitpackages kompiliert wurde.

Ansonsten sind die "Klassen" inkompatibel und du hast nur eine der anderen Wahl(en):
* Status/ErrorCode im Result
* SetLastError/GetLastError
* oder eine eigene "LastError"-Methode (so kann man auch Error-Texte rausgeben)
* u.ä.

nezumi7 31. Jul 2021 14:17

AW: Fehlerbehandlung bei dll
 
@Sebastian
Das ist ja sehr interessant, dass das bei Dir funktioniert! Du sprichst von einem try/except: Hast Du den Aufruf im Host nochmal in ein try except gepackt?

Sehr dankbar bin ich Dir für den Hinweis auf das aktuelle Indy. Ich hatte da gar nicht mehr nachgesehen, weil ich vor einiger Zeit schon mal gelesen hatte, dass Indy nur bis zur Version 10.2 oder sowas mit D6 kompatibel ist. scheinbar unterstützt diese Version aber nur die Protokolle TLS 1.0 und 1.1, die aber von der gewünschten Internetseite nicht mehr akzeptiert werden. Ich hatte daher immer eine "reset by peer" Fehlermeldung bekommen. Ich werds jetzt aber gleich nochmal mit dem aktuellen Indy probieren, das ist mir eh lieber als das Rumgefrickel mit dlls.

@Günther
Ich habe im gesamten restlichen Code kein try/except, weil da eigentlich nichts mehr schief gehen kann. Das einzige try (/ finally) hatte ich oben schon gepostet. Ist Deine Anmerkung so zu verstehen, dass ich besser mit einem try/except (anstelle try/finally) arbeiten sollte, damit die Exception die dll nicht verlässt? (In diese Richtung scheint mir auch der Hinweis von himitsu zu gehen, wobei die Ausführungen für mich aber starker Tobak sind und weit über meinen Hobby-Programmier-Horizont hinausgehen....). :oops:

Bernhard Geyer 31. Jul 2021 14:56

AW: Fehlerbehandlung bei dll
 
Und wie wäre es das Hauptprogramm auf aktuelle Delphi-Version zu bringen.
Wir waren lange selbst auf D6.
Die Produktivitätssprung mit aktuellen Delphi ist gegenüber D6 gewaltig.

jaenicke 5. Aug 2021 14:31

AW: Fehlerbehandlung bei dll
 
Zitat:

Zitat von nezumi7 (Beitrag 1493039)
Du sprichst von einem try/except: Hast Du den Aufruf im Host nochmal in ein try except gepackt?

Ich habe beides ausprobiert. Egal ob ein der DLL oder der Hostanwendung funktioniert das try..except normal wie erwartet.

Zitat:

Zitat von nezumi7 (Beitrag 1493039)
Ich habe im gesamten restlichen Code kein try/except, weil da eigentlich nichts mehr schief gehen kann. Das einzige try (/ finally) hatte ich oben schon gepostet.

Nun ja, wenn du den Fehler gar nicht abfängst, weil du kein try..except drin hast, wird er auch nicht abgefangen...
try..finally reicht die Exception ja weiter, denn es sorgt ja nur dafür, dass der Code im finally trotz eines Fehlers ausgeführt wird. Es fängt die Exception aber nicht ab.
Wenn du das dann an der falschen Stelle aufrufst, mag es auch Folgeprobleme geben.

Rolf Frei 6. Aug 2021 19:00

AW: Fehlerbehandlung bei dll
 
Zitat:

Zitat von nezumi7 (Beitrag 1493039)
@Sebastian
Das ist ja sehr interessant, dass das bei Dir funktioniert! Du sprichst von einem try/except: Hast Du den Aufruf im Host nochmal in ein try except gepackt?

Sehr dankbar bin ich Dir für den Hinweis auf das aktuelle Indy. Ich hatte da gar nicht mehr nachgesehen, weil ich vor einiger Zeit schon mal gelesen hatte, dass Indy nur bis zur Version 10.2 oder sowas mit D6 kompatibel ist. scheinbar unterstützt diese Version aber nur die Protokolle TLS 1.0 und 1.1, die aber von der gewünschten Internetseite nicht mehr akzeptiert werden. Ich hatte daher immer eine "reset by peer" Fehlermeldung bekommen. Ich werds jetzt aber gleich nochmal mit dem aktuellen Indy probieren, das ist mir eh lieber als das Rumgefrickel mit dlls.

@Günther
Ich habe im gesamten restlichen Code kein try/except, weil da eigentlich nichts mehr schief gehen kann. Das einzige try (/ finally) hatte ich oben schon gepostet. Ist Deine Anmerkung so zu verstehen, dass ich besser mit einem try/except (anstelle try/finally) arbeiten sollte, damit die Exception die dll nicht verlässt? (In diese Richtung scheint mir auch der Hinweis von himitsu zu gehen, wobei die Ausführungen für mich aber starker Tobak sind und weit über meinen Hobby-Programmier-Horizont hinausgehen....). :oops:

Delphi-Quellcode:
library internet;

uses
  System.SysUtils,
  System.Classes,
  System.Net.URLClient,
  System.Net.HttpClient,
  System.Net.HttpClientComponent;

{$R *.res}

function get_course(url: ShortString): shortstring; stdcall;
var
  HttpClient: THttpClient;
  HttpResponse: IHttpResponse;
 begin
  Result := '';

  HttpClient := THTTPClient.Create;
  try
    try
      HttpResponse := HttpClient.Get(url);
    except
      // hier irgendwas machen, was du willst z.B. je anch Exeption etwas anderes (Siehe Hilfe zu try except).
      vtext := '';
    end;
    if vtext <> '' then
      vtext := HttpResponse.ContentAsString();
  finally
    HttpClient.Free;
  end;

{es folgt eine längere Auswertung des Seitenquelltextes, der Kurs wird dann ins Result geschrieben. Hier liegt nicht das Problem} 
  end;

exports
  get_course;
begin
end.

jaenicke 6. Aug 2021 20:55

AW: Fehlerbehandlung bei dll
 
Wie soll denn dort vtext etwas anderes als einen Leerstring bekommen?

himitsu 6. Aug 2021 22:10

AW: Fehlerbehandlung bei dll
 
Noch besser, wenn es knallt, dann richtig, da HttpResponse nicht initialisiert wurde, wenn .GET abgeraucht ist.
Aber zum Glück überspringt das IF nach dem EXCEPT-END den Code, damit es nicht knallen kann. :angle2:

Meckert denn der Complier hier nicht über eine "nicht initialisierte Variable" ?


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