Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Object und Fail (https://www.delphipraxis.net/147145-object-und-fail.html)

MacGuyver 2. Feb 2010 18:31


Object und Fail
 
Moin Leute :hi:

Ich stelle gerade mein Programm von Turbo Pascal 7.0 auf Turbo Delphi um. Das Programm läuft dann als Console. Bei über 100.000 Zeilen kann ich nicht mal eben eine reine Formularanwendung draus machen. Als 32 Bit Console läuft das Teil dann auch auf XP 64 Bit, was einer 16 Bit Anwendung verwährt wird.

Komme ich zu meinem Problem.

Delphi-Quellcode:
type
  TDirInfo = object
    DirInfo : SearchRec;

    constructor Create( aDatei : PathStr;
                        aAttr : Word);

    function   FindNext:Boolean;

    destructor Free;
  end;
 
constructor TDirInfo.Create( aDatei : PathStr;
                             aAttr : Word);
{$IfDef Win32}
var
  lEc : Int32;
{$EndIf}

begin
{$IfDef Win32}
  lEc := FindFirst(aDatei,aAttr,DirInfo);
  if lEc <> 0 then
  begin
    SysUtils.FindClose(DirInfo);
    Fail;
  end;
{$Else}
  FindFirst(aDatei,aAttr,DirInfo);
  if DosError <> 0 then
  begin
    { FindClose wird bei Dos nicht benötigt }
    Fail;
  end;
{$EndIf}
end;

function TDirInfo.FindNext:Boolean;

{$IfDef Win32}
var
  lEc : Int32;
{$EndIf}

begin
{$IfDef Win32}
  lEc := SysUtils.FindNext(DirInfo);
  FindNext := lEc = 0;
{$Else}
  Dos.FindNext(DirInfo);
  FindNext := DosError = 0;
{$EndIf}
end;

destructor TDirInfo.Free;

begin
{$IfDef Win32}
  SysUtils.FindClose(DirInfo);
{$EndIf}
end;
Wenn FindFirst keine Datei liefert, wird Fail aufgerufen. In dem Moment zerlegt sich mein Stack und ein folgender FillChar auf eine Variable von Record führt zum Speicherfehler.

Ich könnte wie folgt umstellen:

Delphi-Quellcode:
type
  TDirInfo = object
    DirInfo : SearchRec;

    constructor Create;

    function   FindFirst( aDatei : PathStr;
                           aAttr : Word):Boolean;

    function   FindNext:Boolean;

    destructor Free;
  end;
Leider muss ich dann 38 Stellen in meinem Programm umstellen. Dazu kommen dann noch ein paar Objekte, die auch mit Fail enden, wenn eine Datei nicht geöffnet werden kann, etc. und das sind noch viel mehr Stellen.

Meine Frage: Kommt das wirklich vom Fail? Hat jemand von euch schon Erfahrungen damit gesammelt?



Stefan

implementation 2. Feb 2010 18:49

Re: Object und Fail
 
Zitat:

Zitat von MacGuyver
Delphi-Quellcode:
begin
{$IfDef Win32}
  lEc := FindFirst(aDatei,aAttr,DirInfo);
  if lEc <> 0 then
  begin
    SysUtils.FindClose(DirInfo);
    Fail;
  end;

Gehört FindClose nicht erst nach FindNext?
So läuft das zumindest inner Windows API.

[OT]Du solltest auf Klassen umstellen. Objekte sind inzwischen veraltet.[/OT]



[EDIT]
OK, ich nehm alles zurück. Wird ja nur im Fehlerfall aufgerufen. Sry.
[/EDIT]

MacGuyver 2. Feb 2010 19:00

Re: Object und Fail
 
Ja, object ist veraltet, das weiß ich. Wie du an den ganzen Compilerschalter schon siehst, möchte ich das Programm unter Delphi und unter TP7 kompilieren können.

FindFirst/FindNext/FindClose kann ich ausschließen, habe ich auch erst gedacht.

toms 2. Feb 2010 20:07

Re: Object und Fail
 
Wo wird dem DosError entwas zugewiesen?

MacGuyver 2. Feb 2010 20:20

Re: Object und Fail
 
DosError?

Delphi-Quellcode:
{$IfDef Win32}
  lEc := SysUtils.FindNext(DirInfo);
  FindNext := lEc = 0;
{$Else}
  Dos.FindNext(DirInfo);
  FindNext := DosError = 0;
{$EndIf}
Das wird doch nur in TP kompiliert. Unter Delphi wird

Delphi-Quellcode:
lEc := SysUtils.FindNext(DirInfo);
FindNext := lEc = 0;
ausgeführt.

Blup 3. Feb 2010 12:39

Re: Object und Fail
 
Bei FindClose ist SysUtils angegeben.
Eventuell wird ein falsches FindFirst aufgerufen, vieleicht dann besser so:
Delphi-Quellcode:
{$IfDef Win32}
  lEc := SysUtils.FindFirst(aDatei,aAttr,DirInfo);
SysUtils.FindClose() muss und sollte nur aufgerufen werden, wenn SysUtils.FindFirst erfolgreich war.

MacGuyver 4. Feb 2010 09:40

Re: Object und Fail
 
Irrtum!

FindClose braucht nicht aufgerufen zu werden, wenn nichts gefunden wurde. Wenn etwas gefunden wurde muss es aber aufgerufen werden.

Ich hatte das FindClose auch schon ausgeklammert, der Fehler trat trotzdem auf.

Blup 4. Feb 2010 09:57

Re: Object und Fail
 
Zitat:

Zitat von MacGuyver
Irrtum!

FindClose braucht nicht aufgerufen zu werden, wenn nichts gefunden wurde. Wenn etwas gefunden wurde muss es aber aufgerufen werden.

Du hast meine Antwort nicht richtig gelesen.
Genau das hab ich auch geschrieben.

Zitat:

Zitat von MacGuyver
Ich hatte das FindClose auch schon ausgeklammert, der Fehler trat trotzdem auf.

Du kannst und solltest auf FindClose an dieser Stelle verzichten, aber es geht darum SysUtils.FindFirst und nicht nur FindFirst zu schreiben, den es ist unklar ob eventuell Dos.FindFirst aufgerufen wird.

MacGuyver 4. Feb 2010 12:30

Re: Object und Fail
 
Oh, da habe ich nicht richtig gelesen. :oops:

Die Unit DOS enthält nur PathStr und Co. und sonst nichts. Sie ist nur ein Dummy, damit ich nicht jede Unit überarbeiten muss. Mein Konvertierungsprogramm fügt die SysUtils überall automatisch ein, so sind die Funktionen wie BlockRead und so drin.

Von daher nimmt er die aus SysUtils. In Windows.pas gibt es kein FindFirst, was er fälschlicher Weise nehmen könnte. Es wird von FindFirst auf FindFirstFile aus Windows.pas zugegriffen.

MacGuyver 4. Feb 2010 20:32

Re: Object und Fail
 
N'abend,

ich habe das gerade noch einmal durchgespielt. Ich habe das Objekt so umgestellt, dass das FindFirst in einer Funktion verwendet wird und im Creator kein Fail mehr verwendet wird. Der Fehler auf dem Stack passiert so nicht mehr.

So ein Mist! 150 Stellen überarbeiten. :kotz:

Hätte ich das mal früher gewusst...


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