AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Auf Fehlerrückgabe prüfen

Ein Thema von DelphiManiac · begonnen am 25. Jul 2007 · letzter Beitrag vom 25. Jul 2007
Antwort Antwort
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#1

Auf Fehlerrückgabe prüfen

  Alt 25. Jul 2007, 09:28
Hallo,

ich habe ein Designproblem bei meiner Gestaltung meines Quelltextes:

Ich habe ein API Klasse zu Steuerung eines Gerätes entworfen, die kann u.a. folgendes:

Delphi-Quellcode:
TGeraet.GetUhrzeit(var uhrzeit:TUhrzeit):integer;
TGeraet.GetParamter(var paramter:Word):integer;
TGeraet.GetSeriennummer(var sn:string):integer;
die Methoden geben einen Fehlercode zurück:

0 -> kein Fehler
120 -> Timeout
130 -> Checksum Error...

Nun finde ich es irgendwie blöd jedes mal wenn ich eine Methode aufrufe
dieses zu machen

Delphi-Quellcode:
if (meinGeraet.GetSeriennummer(sn) <>0) then
begin
  // Fehlerbehandlung
end;
...
if (meinGeraet.GetUhrzeit(uz) <>0) then
begin
  // Fehlerbehandlung
end;
da ich sehr viele Kommunikationsanfragen habe und das ganze meinen Quelltext aufquellt

Danke vielleicht wisst ihr ja eine vielleicht auch OOP-Design-Lösung

Gruß
DelphiManiac
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Auf Fehlerrückgabe prüfen

  Alt 25. Jul 2007, 09:47
dann gib anstelle des Integers einen Bool zurück und den Feherlode als optionalen Parameter. Oder den Fehlercode im Bool (ein Bool kann schließlich nicht nur 1 und 0 sein) wobei der Bool dann genau das umgekehrte Ergebnis ist.

mit dem optionalen Fehlercode würde es so aussiehen
Delphi-Quellcode:
function TGeraet.GetUhrzeit(var uhrzeit:TUhrzeit; AResultCode: PInteger=nil):Boolean;
begin
  [...]
  if Assigned(AResultCode) then
    ResultCode^ := bisherigerRueckgabewert;
  result := bisherigerRueckgabewert = 0;
end;
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Auf Fehlerrückgabe prüfen

  Alt 25. Jul 2007, 09:50
Vielleicht hilft dir die Aufrufkonvention SAFECALL.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#4

Re: Auf Fehlerrückgabe prüfen

  Alt 25. Jul 2007, 09:59
Du kannst ja auch Exceptions verwenden.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#5

Re: Auf Fehlerrückgabe prüfen

  Alt 25. Jul 2007, 12:27
@sirius: Was mach den genau die Aufrufkonvention SAFECALL?

@Dezipaitor: wie genau würdest du sowas mit Exceptions lösen? würdest du eine Exception werfen?

Thx
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Auf Fehlerrückgabe prüfen

  Alt 25. Jul 2007, 12:48
Wenn du Exception werfen kannst, ist das doch das einfachste. Falls das nicht geht, dann arbeite mit SafeCall (ist ja auch das, was man u.U. bei Interfaces macht)

Ich dachte du hattest Exception schon ausgeschlossen, aber wenn nicht, dann nimm lieber diesen Weg.

Exceptions:
Delphi-Quellcode:
interface

type UhrzeitException=class(Exception);
//... und noch andere Exceptions


implementation


function TGeraet.GetUhrzeit:TUhrzeit;
begin
  //...
  if Fehler then raise UhrzeitException.create('wenn du magst, dann hier noch ein Text');
end;
Beim Aufrufen:
Delphi-Quellcode:

try
  xyz:=meingeraet.getuhrzeit;
  //...andere Abfragen

except
 on UhrzeitException do Uhrzeitfehler
 on ... do ...
 //...
 else raise;
end;
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Auf Fehlerrückgabe prüfen

  Alt 25. Jul 2007, 12:53
@sirius: ich glaube der Fragesteller ist wie ich davon ausgegangen das du die CallingConvention SaveCall meintest. Und das würde ja keinen wirklichen Sinn machen?! Denn das würde ja nur bestimmen wie die Parameterübergabe erfolgt (in welcher Reihenfolge, ob über Register etc.).
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#8

Re: Auf Fehlerrückgabe prüfen

  Alt 25. Jul 2007, 13:04
@SirThornberry:

Ja genau, die Parameterübergabe ist hier ja schon geregelt, und da gibt es auch keine Vorschriften.
Mir ging es nur darum einen auftretenden Fehler zu melden und diesen abzuhandeln.

Und vorallendingen wollte ich nicht immer den Rückgabewert prüfen müssen bei jedem Funktionsaufruf...

Muss zugeben, ich nutze Exceptions viel zu selten, ist es denn hier generell sinvoll eine Exception zu werfen,

wie verhält sich denn das Programm, wenn ich in meiner Funktion erkenne, dass ein Fehler vorlag, und dann eine
Exception auslöse?

Gruß
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Auf Fehlerrückgabe prüfen

  Alt 25. Jul 2007, 13:16
@Sir: Das ist auch richtig. SAFECALL hat aber neben der Angabe über Parameterübergabe etc. auch noch einen weiteren Hintergrund. Eine SafeCall-Funktion hat immer zwei Rückgabewerte (eine Prozedur dementsprechend immer einen), zum einen das "echte Ergebnis", zum anderen einen Fehlercode.
Hintergrund ist der, dass man in der OOP ja keine Klassen kreuz und quer durch verschiedene Adressbereiche bzw. Speichermanager etc. schieben kann. Konkret (wobei ... jetzt bin ich mir nicht 100% sicher): Du kannst keine Klasse in einer Library erstellen und in deiner Main-Exe freigeben (ohne Sharemem etc.). Bei Exceptions (in OOP) würde genau das passieren. Beim Werfen der Exception wird die Klasse erstellt und hinterm nächsten except gekillt. -->CRASH

Dagegen gibts SafeCall: Du machst die Exceptionbehandlung innerhalb der Bibliothek und gibst neben dem eigentlichen Ergebnis auch einen Fehlercode mit zurück. Der Compiler prüft nach dem Aufruf einer SafeCall-Funktion automatisch den Fehlercode und ruft gegebenenfalls die Funktion in der Variablen SafeCallErrorProc auf (die normalerweise nil ist). Ausserdem wirft er erneut eine SafeCallException.
Das ist das besondere an SafeCall und entspricht so ziemlich dem was DelpiManiac als Funktionsköpfe hatte.
Also eine Funktion
function xyz(a,b,c,...:integer; var result:integer):TErrorCode; stdcall; ist dasselbe wie
function xyz(a,b,c,...:integer):integer; safecall; vom Header her (mit TErrorCode=integer)

So, und jetzt wirds dirty (vielleicht gehts auch einfacher, aber Delphi übergibt sonst immer denselben Fehlercode):
Delphi-Quellcode:
//Die Funktion in einer Bibliothek
function test(var erg:integer):cardinal;stdcall;
//hier allerdings lieber stdcall, weil wir wollen ja den ErrorCode selber setzen
const Error=$80000000; //Vorzeichenbit muss gesetzt sein für Fehler
begin
  //der eigentliche Funktionsinhalt
  erg:=-5;


  
  //wenn Fehler dann
  result:=120+error; //120 unser Fehlercode
  //sonst
  result:=0; //hauptsache nicht negativ
end;
Und im Hauptprogramm:
Delphi-Quellcode:
var ExceptionType:integer;

procedure SafecallError;
asm
  //die ersten beiden Zeilen nutzen wenn keine Exception geworfen werden soll
  //pop ecx
  //mov [esp],edx

  //Ergebnis in Exceptiontype schreiben
  and eax,$7FFFFFFF
  mov ExceptionType,eax
end;

procedure TForm1.Button1Click(Sender: TObject);
var mytest:function:integer;safecall;
begin
  
  mytest:=@test;
  try
    edit1.Text:=inttostr(mytest);
  except
    on ESafeCallException do
      edit1.text:=inttostr(Exceptiontype);
    else raise;
  end;
end;
Soweit, so gut. Und irgendwo vorher muss noch
safecallerrorProc:=@SafeCallError; gesetzt werden.

War hier nur so ne Idee...die auch erstmal funktioniert

Edit:
Wenn man in SafeCallError alle auskomentierten Zeilen so lässt, geht es auch ohne ASM:
Delphi-Quellcode:
procedure safecallerror(ErrorCode:integer;NonExceptionAddr:pointer);
begin
  ExceptionType:=Errorcode and $7FFFFFFF;
end;
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Auf Fehlerrückgabe prüfen

  Alt 25. Jul 2007, 13:23
Zitat von DelphiManiac:
wie verhält sich denn das Programm, wenn ich in meiner Funktion erkenne, dass ein Fehler vorlag, und dann eine
Exception auslöse?
Bei "raise" wird die Exception ausgelöst und jetzt springt das Programm bis zum nächsten Except (auch in übergeordneten Funktionen) und macht dort ganz normal weiter. Wenn es so ein except nicht gibt, kommt die Fehlermeldung mit dem kreativen Text, den du eingegeben hast, auf dem Bildschirm.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  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 06:37 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