Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi CopyFileEx und Codeoptimierung XE5 (https://www.delphipraxis.net/179923-copyfileex-und-codeoptimierung-xe5.html)

wurzelzwerg 10. Apr 2014 22:58


CopyFileEx und Codeoptimierung XE5
 
Moin zusammen,

ich benutze DelphiXE5. CopyFileEx funktioniert da nicht wenn ich Codeoptimierung aktiv habe. :shock:
D.h. es kommt der Fehler "Die Anforderung wurde abgebrochen"
Delphi-Bug oder gibts dafür eine andere Erklärung?

Danke

Union 11. Apr 2014 01:23

AW: CopyFileEx und Codeoptimierung XE5
 
Die irrsinnige Menge des von Dir geposteten Sourcecodes hat mich fast zur Verzweiflung getrieben :roll:

wurzelzwerg 11. Apr 2014 08:09

AW: CopyFileEx und Codeoptimierung XE5
 
Wozu sourcecode? Der ist ja kaum falsch wenn es ohne Optimierung funktioniert.
Ausserdem ist der älter, d.h. in 2006 gabs auch mit Optimierung keine Fehler.

Delphi-Quellcode:
[B]
function TFileCopier.DoFolderFiles( const ASourcePath, ATargetPath: string;
                                    const Op: TFolderOp): Int64;

var
  StrName,
  MySearchPath,
  MyTargetPath,
  MySourcePath: string;
  FindRec: TSearchRec;
  i: Integer;
  Cancelled: Boolean;
  Attrs: integer;
  CopyIt: boolean;
begin
  Result := 0;
  Cancelled := False;
  MyTargetPath := AddBackSlash(ATargetPath);
  MySourcePath := AddBackSlash(ASourcePath);
  MySearchPath := AddBackSlash(ASourcePath) + '*.*';
  i := FindFirst(MySearchPath, 0 , FindRec);

  try
    while (i = 0) and (Result <> -1) do
    begin
      try
      case op of
       foCopy: begin
          StrName := MySourcePath + FindRec.Name;
          CopyIt:= CopyAll or (FindRec.Attr and faArchive = faArchive);
          if CopyIt then
          begin
            //Cancelled:= false;
            if CopyFileEx(PWideChar(StrName), PWideChar(MyTargetPath + FindRec.Name), @fCallBack, Pointer(fHandle), @Cancelled, 0) then
            begin
              Attrs := FileGetAttr(StrName);
              FileSetAttr(StrName, Attrs and not faArchive);
              inc(Result);
              inc(fCopyCount);
              TUtils.WriteLogFile(eData, StrName + ' saved to ' + MyTargetPath + FindRec.Name);
              Sleep(50);
            end
            else
            begin
              Result := -1;
              TUtils.WriteLogFile(eError, StrName + ' not saved' + #13#10 + SysErrorMessage (GetLastError));
            end;
          end;
        end;
       foCount:
       begin
         Inc(Result);
         Inc(fFileCount);
       end;
       foSize:
       begin
         Result := Result + FindRec.Size;
         fFileSize := fFileSize + FindRec.Size;
       end;
      end; // case
      except
        Result := -1;
      end;
      i := FindNext(FindRec);
    end;
  finally
    FindClose(FindRec);
  end;

end;

[/B]

Union 11. Apr 2014 08:36

AW: CopyFileEx und Codeoptimierung XE5
 
Diese Zuweisungen werden wegoptimiert, weil die Variable aus Sicht des Compilers später nicht mehr angesprochen wird:
Delphi-Quellcode:
Cancelled:= false;
Wenn Du das Flag später nochmal abfragst könnte es gehen.

wurzelzwerg 11. Apr 2014 08:50

AW: CopyFileEx und Codeoptimierung XE5
 
Die Zeile gehört eigentlich nicht rein, war nur um das zu finden.
Das setzt man auf true um während des kopierens abzubrechen. So weit kommt man aber erst garnicht.

Union 11. Apr 2014 08:53

AW: CopyFileEx und Codeoptimierung XE5
 
Liegt der Fehler evtl. im Callback?

Der schöne Günther 11. Apr 2014 08:55

AW: CopyFileEx und Codeoptimierung XE5
 
Laut API-Dokumentation ist aber doch genau das der Grund wenn er mit
Delphi-Quellcode:
ERROR_REQUEST_ABORTED
rausgeht.

Der andere wäre, wenn dein
Delphi-Quellcode:
fCallBack
Delphi-Quellcode:
PROGRESS_STOP
zurückgibt, aber über das Ding wissen wir nichts.

wurzelzwerg 11. Apr 2014 08:59

AW: CopyFileEx und Codeoptimierung XE5
 
Nein, ohne callback(nil) das gleiche Problem.

Am Cancel liegt das nicht, das war vorher auch dort nicht drin, brauch ich auch nicht.
Die Funktion wird sofort abgebrochen. Aber eben nur wenn Optimierung an ist.

pbCancel [in, optional]
If this flag is set to TRUE during the copy operation, the operation is canceled. Otherwise, the copy operation will continue to completion.


Callback sendet nur Messages, aber wie gesagt ohne Callback gehts auch nicht.
Delphi-Quellcode:
function CopyFileProgress(TotalFileSize, TotalBytesTransferred, StreamSize,
  StreamBytesTransferred: LARGE_INTEGER; dwStreamNumber, dwCallbackReason,
  hSourceFile, hDestinationFile: DWORD; lpData: Pointer): DWORD; stdcall;
begin
  if CancelCopy = True then
  begin
    SendMessage(THandle(lpData), CEXM_CANCEL, 0, 0);
    result:= PROGRESS_CANCEL;
    exit;
  end;
  case dwCallbackReason of
    CALLBACK_CHUNK_FINISHED:
      begin
        SendMessage(THandle(lpData), CEXM_CONTINUE, TotalBytesTransferred.LowPart, TotalBytesTransferred.HighPart);
        result:= PROGRESS_CONTINUE;
      end;
    CALLBACK_STREAM_SWITCH:
      begin
        SendMessage(THandle(lpData), CEXM_MAXBYTES, TotalFileSize.LowPart, TotalFileSize.HighPart);
        result:= PROGRESS_CONTINUE;
      end;
  else
    result:= PROGRESS_CONTINUE;
  end;
end;

himitsu 11. Apr 2014 09:15

AW: CopyFileEx und Codeoptimierung XE5
 
Einen Fehle seh ich auf die Schnelle auch noch nicht,

aber im Notfall könntest du ja die Optimierung für die eine einfach Funktion deaktivieren.

Der schöne Günther 11. Apr 2014 09:28

AW: CopyFileEx und Codeoptimierung XE5
 
Du meinst also, ein reines
Delphi-Quellcode:
   if not CopyFileEx(
      'd:\Neues Textdokument.txt',
      'd:\Neues Textdokument (Kopie).txt',
      nil, nil, nil,
      COPY_FILE_NO_BUFFERING
   ) then RaiseLastOSError();
fliegt schon raus?

wurzelzwerg 11. Apr 2014 09:42

AW: CopyFileEx und Codeoptimierung XE5
 
Deine Version geht.

Das fliegt raus:

Delphi-Quellcode:
var
  Cancelled: Boolean;
begin
  if not CopyFileEx('d:\Neues Textdokument.txt',
      'd:\Neues Textdokument (Kopie).txt',
      nil, nil, @Cancelled,
      COPY_FILE_NO_BUFFERING
   )
   then RaiseLastOSError();
Jetzt komischerweise unabhängig von Code-Optimierung, also immer.
:o

Im ursprünglichen Programm muss das @Cancelled raus und nil rein dann gehts auch dort.
Nur Warum?

Uwe Raabe 11. Apr 2014 09:49

AW: CopyFileEx und Codeoptimierung XE5
 
Die lokale Variable
Delphi-Quellcode:
Cancelled
wird nicht implizit initialisiert. Wenn da zufällig
Delphi-Quellcode:
true
drin steht, würde das
Delphi-Quellcode:
CopyFileEx
abbrechen. Selbst wenn du die vorher auf
Delphi-Quellcode:
false
setzt, wird der Compiler den Aufruf wegoptimieren, da die Variable später nicht ausgelesen wird. Offenbar wird die Übergabe an
Delphi-Quellcode:
CopyFileEx
über den Adressoperator nicht als Verwendung angesehen.

Versuch doch mal einfach nach dem
Delphi-Quellcode:
CopyFileEx
noch eine Abfrage auf
Delphi-Quellcode:
Cancelled
zu machen (natürlich so, daß die nicht auch noch wegoptimiert wird).

Der schöne Günther 11. Apr 2014 09:56

AW: CopyFileEx und Codeoptimierung XE5
 
Vielleicht würde
Delphi-Quellcode:
Addr(Cancelled)
statt
Delphi-Quellcode:
@Cancelled
einen Unterschied bzgl. Optimierung machen? (Ich rate nur wild)

himitsu 11. Apr 2014 10:07

AW: CopyFileEx und Codeoptimierung XE5
 
Ob und welches
Delphi-Quellcode:
Cancelled := False;
wegoptimiert wurde, müsste man nach dem Compilieren eigentlich sehen (die blauen Pünktchen) und auch der Debugger würde die Befehle entsprechend überspringen.

Zitat:

Zitat von Uwe Raabe (Beitrag 1255312)
(natürlich so, daß die nicht auch noch wegoptimiert wird).

Ist der Compiler eigentlich inzwischen so intelligent, daß er auch leere IFs erkennt?
Oder optimiert er
Delphi-Quellcode:
if Cancelled then ;
immernoch nicht weg? :angel:

wurzelzwerg 11. Apr 2014 10:08

AW: CopyFileEx und Codeoptimierung XE5
 
Hilft beides nicht.
Cancelled ist davor und danach false und CopyFileEx fliegt raus.

Delphi-Quellcode:
var
  Cancelled: Boolean;
begin
  Cancelled:= false;
  if not CopyFileEx('d:\Neues Textdokument.txt',
      'd:\Neues Textdokument (Kopie).txt',
      nil, nil, @Cancelled,
      COPY_FILE_NO_BUFFERING
   )
   then RaiseLastOSError();
   if Cancelled then
     beep;

Union 11. Apr 2014 10:46

AW: CopyFileEx und Codeoptimierung XE5
 
Delphi-Quellcode:
if CompilerVer > D2009 then LongBool <> Boolean;

DeddyH 11. Apr 2014 10:56

AW: CopyFileEx und Codeoptimierung XE5
 
War Boolean nicht immer schon ByteBool?

Union 11. Apr 2014 11:14

AW: CopyFileEx und Codeoptimierung XE5
 
Ja ;) Aber in diesem Fall liegt es an den Variablen. Bei ausgeschalteter Optimierung belegt wohl das boolean eine Registerbreite. Ist sie angeschaltet dann wird nur noch ein Byte belegt. Jetzt wird ein Pointer auf die Adresse des boolean an die CopyFileEx übergeben. Dieses ist der festen Überzeugung das es 4 byte lesen muss und darf. Damit hängt der Inhalt aus Sicht der WinApi davon ab, was dahinter gerade so zufällig an den nächsten 3 byte im Speicher steht.

wurzelzwerg 11. Apr 2014 11:28

AW: CopyFileEx und Codeoptimierung XE5
 
Danke, das wars. Mit LongBool gehts.

Christian Seehase 11. Apr 2014 11:35

AW: CopyFileEx und Codeoptimierung XE5
 
Zitat:

Zitat von DeddyH (Beitrag 1255321)
War Boolean nicht immer schon ByteBool?

Bis D7 zurück auf jeden Fall.
(kleiner kann ich im moment nicht prüfen ;-))

Sir Rufo 11. Apr 2014 11:39

AW: CopyFileEx und Codeoptimierung XE5
 
Die Erklärung ist auch unter CopyFileEx und Windows Data Types zu finden.

Delphi-Quellcode:
pbCancel
ist vom Typ ein
Delphi-Quellcode:
LPBOOL
, der wiederum ein Pointer auf ein
Delphi-Quellcode:
BOOL
ist und das ist vom Typ ein
Delphi-Quellcode:
INT
.

Ein
Delphi-Quellcode:
BOOLEAN
ist ein
Delphi-Quellcode:
BYTE
.

Ich habe aber auch erst jetzt nachgesehen ;)

Der schöne Günther 11. Apr 2014 12:28

AW: CopyFileEx und Codeoptimierung XE5
 
Alter Schwede, den Fehler habe ich dann aber auch schon ein paar mal gemacht! :shock:

Bislang ist mir noch nichts um die Ohren geflogen...

DeddyH 11. Apr 2014 12:28

AW: CopyFileEx und Codeoptimierung XE5
 
Bei LPBOOL böte sich der generische Typ BOOL an (in Windows.pas als LongBool deklariert), dann sollte das doch automatisch passen, oder?

Uwe Raabe 11. Apr 2014 12:33

AW: CopyFileEx und Codeoptimierung XE5
 
Zitat:

Zitat von DeddyH (Beitrag 1255330)
Bei LPBOOL böte sich der generische Typ BOOL an (in Windows.pas als LongBool deklariert), dann sollte das doch automatisch passen, oder?

Genau dafür gibt es den ja auch.

DeddyH 11. Apr 2014 12:34

AW: CopyFileEx und Codeoptimierung XE5
 
Ja eben :)

wurzelzwerg 11. Apr 2014 13:09

AW: CopyFileEx und Codeoptimierung XE5
 
Das perverse war ja dass es bei mir ohne Codeoptimierung funktioniert hat. :shock:

Uwe Raabe 11. Apr 2014 13:34

AW: CopyFileEx und Codeoptimierung XE5
 
Zitat:

Zitat von wurzelzwerg (Beitrag 1255338)
Das perverse war ja dass es bei mir ohne Codeoptimierung funktioniert hat. :shock:

Das liegt wohl eher an den zufälligen Werten in den 3 höheren Bytes, die mit und ohne Optimierung halt andere Inhalte haben. War das jetzt sowas wie ein Mini-Heartbleed?

wurzelzwerg 11. Apr 2014 13:54

AW: CopyFileEx und Codeoptimierung XE5
 
Random Bug :lol:
Na gut, habs grad noch überlebt :stupid: :cheers:

himitsu 11. Apr 2014 16:33

AW: CopyFileEx und Codeoptimierung XE5
 
Ich finde es ja praktisch, daß inzwischen immer mehr dieser APIs entweder direkt mit einem VAR-Parameter deklariert wurden, oder dass es davon eine entsprechende überladene Version gibt.

Dort schlägt dann die Typprüfung des Compilers zu und der Fehler wird schnell entdeckt.

uligerhardt 12. Apr 2014 16:22

AW: CopyFileEx und Codeoptimierung XE5
 
Zitat:

Zitat von himitsu (Beitrag 1255364)
Ich finde es ja praktisch, daß inzwischen immer mehr dieser APIs entweder direkt mit einem VAR-Parameter deklariert wurden, oder dass es davon eine entsprechende überladene Version gibt.

Dort schlägt dann die Typprüfung des Compilers zu und der Fehler wird schnell entdeckt.

Wenn man in den Compileroptionen "Typisierter Adressoperator" einschaltet, hätte der Compiler hier vermutlich auch gemeckert. Ärgerlich, dass das defaultmäßig deaktiviert ist.


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