Delphi findclose ошибка

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.


    Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
    1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
    2. Как «свернуть» программу в трей.
    3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
    4. Как прочитать список файлов, поддиректорий в директории?
    5. Как запустить программу/файл?
    … (продолжение следует) …


    Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
    Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


    Внимание
    Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
    Повторная попытка — 60 дней. Последующие попытки бан.
    Мат в разделе — бан на три месяца…

    >
    FindClose
    , Ошибка при компиляции

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему



    Сообщ.
    #1

    ,

      В программе многакратно производится поиск файлов. Его я реализовал при помощи стандартных функций FindFirst, FindNext, FindClose. После того, как в разделе Uses был объявлен модуль Windows стала вылетать ошибка на строке FindClose. Как справиться с этой проблемой?
      Я, конечно, понимаю, что самый простой способ — убрать объявление модуля Windows, но нет ли другого способа? : )

      Guru

      Miscђka



      Сообщ.
      #2

      ,

        что за ошибка? Как организован поиск?


        Domino



        Сообщ.
        #3

        ,

          ExpandedWrap disabled

            if FindFirst(‘*.txt’,faAnyFile,SR)=0 then

              repeat

                inc(c) //счетчик файлов

              until FindNext(SR)<>0;

            FindClose(SR); //в этой строчке компилятор ругается

          А на что именно ругается, точно не помню, но точно ему не нравится присутствие в этой строчке типа Cardinal. Причем, повторяю, программа компилировалась безошибочно, и перестала компилироваться после того, как изменилась строка uses:

          ExpandedWrap disabled

            uses

              SysUtils, Windows; // после добавления модуля Windows стала вылетать ошибка компиляции

          Guru

          Miscђka



          Сообщ.
          #4

          ,

            Цитата Denny, 25.10.04, 14:55

            ему не нравится присутствие в этой строчке типа Cardinal

            ну дык, дай ему integer


            Domino



            Сообщ.
            #5

            ,

              Цитата

              ну дык, дай ему Integer

              Ну дык как?
              Переменная SR объявлена как TSearchRec. Я ее Cardinal‘ом не назначал.


              Song



              Сообщ.
              #6

              ,

                Цитата Denny, 25.10.04, 12:18

                FindClose. После того, как в разделе Uses был объявлен модуль Windows стала вылетать ошибка на строке FindClose. Как справиться с этой проблемой?

                SysUtils.FindClose(..

                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                0 пользователей:

                • Предыдущая тема
                • Delphi: Общие вопросы
                • Следующая тема

                Рейтинг@Mail.ru

                [ Script execution time: 0,0406 ]   [ 16 queries used ]   [ Generated: 21.09.23, 09:54 GMT ]  

                При использовании функции FindClose в Delphi может возникнуть ошибка, если она вызывается для уже закрытого файла или имеет неверный дескриптор файла. Это может произойти, если функция FindFirst не была вызвана перед FindClose или было вызвано несколько FindClose для одного дескриптора файла. Чтобы избежать этой ошибки, убедитесь, что FindClose вызывается только после вызова FindFirst и не вызывается несколько раз для одного и того же дескриптора файла.Пример кода на Delphi:var SearchRec: TSearchRec;begin if FindFirst('C:\Users\UserName\Documents\*.txt', faAnyFile, SearchRec) = 0 then begin // файлы найдены repeat // обработка файлов until FindNext(SearchRec) <> 0; FindClose(SearchRec); end;end;В этом примере мы ищем все файлы с расширением .txt в директории пользователя и проходимся по каждому найденному файлу до тех пор, пока не будут найдены все файлы и не будет вызвана функция FindClose для закрытия дескриптора файла. Обратите внимание, что несоблюдение порядка вызовов FindFirst, FindNext и FindClose может привести к ошибке или утечке ресурсов.

                How to Install Delphi 10.4 on Windows 10/11 FREE

                Функции и возможности Delphi DS150E

                Программирование в Delphi. Урок 13.1. Отладка, поиск ошибок Debug

                Embarcadero Delphi Обзор преимуществ / Установка / Удаление / Community Edition IDE / 2022 Бесплатно

                Восстановление прошивки AutoCom CDP+ из состояния кирпича (горит красным и не прошивается)

                Delphi 2021/ 2022 Probleme ( An internal error has occurred )

                Victor031

                0 / 0 / 1

                Регистрация: 11.05.2013

                Сообщений: 29

                1

                03.11.2013, 23:08. Показов 1311. Ответов 3

                Метки нет (Все метки)


                Студворк — интернет-сервис помощи студентам

                Доброго времени суток, уважаемые! Суть проблемы в следующем: делфи ругается на процедуру FindClose. Подскажите в чем ошибка? Зараннее спасибо!

                Delphi
                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                13
                14
                15
                16
                17
                18
                19
                20
                21
                22
                23
                24
                25
                26
                27
                28
                29
                30
                31
                32
                33
                34
                35
                36
                37
                38
                39
                40
                41
                42
                
                unit Unit1;
                 
                interface
                 
                uses
                  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
                  Dialogs, StdCtrls, ExtCtrls;
                 
                type
                  TForm1 = class(TForm)
                    Edit1: TEdit;
                    Edit2: TEdit;
                    Button1: TButton;
                    Label1: TLabel;
                    Label2: TLabel;
                    RadioGroup1: TRadioGroup;
                    procedure Button1Click(Sender: TObject);
                  private
                    { Private declarations }
                  public
                    { Public declarations }
                  end;
                 
                var
                  Form1: TForm1;
                 
                implementation
                 
                {$R *.dfm}
                 
                procedure TForm1.Button1Click(Sender: TObject);
                var
                SearchRec:TSearchRec ;
                begin
                if FindFirst(Edit1.Text,faAnyFile,SearchRec)=0 then
                Edit2.Text:=IntToStr(SearchRec.Size)+' áàéò'
                FindClose(searchRec); //Вот тут ошибка(((
                 
                 
                end;
                 
                end.

                Скрин:



                0



                angstrom

                03.11.2013, 23:44

                2

                Ошибка выше, нет точки с запятой.

                cotseec

                Пишу на Delphi…иногда

                1423 / 1278 / 286

                Регистрация: 03.12.2012

                Сообщений: 3,914

                Записей в блоге: 5

                03.11.2013, 23:46

                3

                в строке перед FindClose

                Delphi
                1
                2
                3
                
                ...
                Edit2.Text:=IntToStr(SearchRec.Size)+' байт';//вот тут ТОЧКА с ЗАПЯТОЙ
                ....

                поставь точку с запятой



                1



                0 / 0 / 1

                Регистрация: 11.05.2013

                Сообщений: 29

                04.11.2013, 00:01

                 [ТС]

                4

                Благодарствую!



                0



                The following is a snippet of code from my ap:

                var DirInfo: TSearchRec;
                begin
                     ChDir(ThisDir);
                     SInfo := 0;
                     N := FindFirst(‘*.*’,faDirectory,DirInfo);
                     While N = 0 do
                     begin
                          If (DirInfo.Name <> ‘.’) AND (DirInfo.Name <> ‘..’) AND (DirInfo.Attr = faDirectory) then
                          begin
                               SInfo := SInfo+1;
                               SetInfo[SInfo].Path := ThisDir+’\’+DirInfo.Name;
                          end;
                          N := FindNext(DirInfo);
                     end;
                     FindClose(DirInfo);
                end;

                When I try to compile it I get the error message «Incompatible types: «Cardinal» and «TSearchRec» on the line FindClose(DirInfo);

                What am I doing wrong?

                Topic: FindClose(FileInfo) — wierd error  (Read 8866 times)

                EDIT —  I’ve just re-checked the declaration and find that the second project is using a different FilUtilh.inc file which declares FindClose as
                Procedure FindClose (Var F : TUnicodeSearchrec);

                I haven’t specified anything different as far as ‘INC’ paths are concerned  in fact that is another question I have been meaning to ask — where DO you set a specific ‘INC’ folder?  but more important for now how can I force the first project’s FilUtilh.inc file to be used?

                Second EDIT  —  On closer reading I now see that FindClose is declared twice in the same .INC file.

                Is there anything wrong with me commenting out the ‘TUnicodeSearchrec’ version?   along with the FindFirst and FindNext TUnicodeSearchrec versions?

                ======================================
                I have two projects using similar code to read filenames from disk. FindFirst is followed by FindNext and finally FindClose.

                One project (with this procedure) :

                1. procedure FindLogs;

                2. Var

                3.   FileInfo : TSearchRec;

                4.   i : byte;

                5. begin

                6.   Form1.LogList.Items.Clear;

                7. if FindFirst(DataPath+‘*.log’,faAnyFile,FileInfo) = 0 then

                8. begin

                9.       Form1.LogList.Items.Add(FileInfo.Name);

                10. Repeat

                11. if FindNext(FileInfo)=0 then

                12. begin

                13.             Form1.LogList.Items.Add(FileInfo.Name);

                14. end;

                15. until FindNext(FileInfo)<>0;

                16. end;

                17.   FindClose(FileInfo);

                18. end;

                compiles and runs perfectly.

                The second — with this code :

                1. procedure FindFiles;

                2. Var

                3.   FileInfo : TSearchRec;

                4.   i,p : byte;

                5. begin

                6.   Form1.Height := 440;

                7.   ReadPath;

                8.   i := 0;

                9. if FindFirst(MusicPath+‘*.pdf’,faAnyFile,FileInfo) = 0 then

                10. begin

                11.       P_List[i] := FileInfo.Name;

                12. Repeat

                13.         inc(i);

                14. if FindNext(FileInfo)=0 then

                15. begin

                16.             P_List[i] := FileInfo.Name;

                17. end;

                18. until (FindNext(FileInfo)<>0) or (i=21);

                19. end;

                20.   FindClose(FileInfo);

                21. end;

                Won’t compile, complaining Error: Incompatible type for arg no. 1: Got «TRawbyteSearchRec», expected «QWord» at FindClose(FileInfo).

                I’ve checked that both projects are set to the same ‘bittness’ (actually tried both 32 and 64).

                I’ve also checked the declaration of FindClose in FilUtilh.inc which is :
                Procedure FindClose (Var F : TRawByteSearchrec);
                so fail to understand why it’s expecting a QWord.

                In the second project, I need to go on to find other files (with a different extension) so assume that I need to call FindClose before doing so.

                « Last Edit: June 13, 2017, 08:10:17 pm by J-G »


                Logged

                FPC 3.0.0 — Lazarus 1.6 &
                FPC 3.2.2  — Lazarus 2.2.0 
                Win 7 Ult 64


                I have two projects using similar code to read filenames from disk. FindFirst is followed by FindNext and finally FindClose.

                Just to nit-pick, but you are calling FindClose() in the wrong place.  It should be inside the first ‘if’ block.  Don’t call FindClose() if FindFirst() fails:

                1. if FindFirst(DataPath+‘*.log’,faAnyFile,FileInfo) = 0 then

                2. begin

                3. FindClose(FileInfo); // <— here

                4. end;

                5. // <— not here!

                Also, a better way to write the loops you have shown would look more like this instead:

                1.

                1. procedure FindLogs;

                2. var

                3.   FileInfo : TSearchRec;

                4. begin

                5.   Form1.LogList.Items.BeginUpdate;

                6. try

                7.     Form1.LogList.Items.Clear;

                8. if FindFirst(DataPath + ‘*.log’, faAnyFile, FileInfo) = 0 then

                9. try

                10. repeat

                11.         Form1.LogList.Items.Add(FileInfo.Name);

                12. until FindNext(FileInfo) <> 0;

                13. finally

                14.       FindClose(FileInfo);

                15. end;

                16. finally

                17.     Form1.LogList.Items.EndUpdate;

                18. end;

                19. end;

                2.

                1. procedure FindFiles;

                2. var

                3.   FileInfo : TSearchRec;

                4.   i : byte;

                5. begin

                6.   Form1.Height := 440;

                7. for i := 0 to 20 do begin

                8.     P_List[i] := »;

                9. end;

                10.   ReadPath;

                11.   i := 0;

                12. if FindFirst(MusicPath + ‘*.pdf’, faAnyFile, FileInfo) = 0 then

                13. try

                14. repeat

                15.       P_List[i] := FileInfo.Name;

                16.       inc(i);

                17. until (i = 21) or (FindNext(FileInfo) <> 0);

                18. finally

                19.     FindClose(FileInfo);

                20. end;

                21. end;

                Alternatively:

                1. procedure FindFiles;

                2. var

                3.   FileInfo : TSearchRec;

                4.   i : byte;

                5. begin

                6.   Form1.Height := 440;

                7. for i := 0 to 20 do begin

                8.     P_List[i] := »;

                9. end;

                10.   ReadPath;

                11. if FindFirst(MusicPath + ‘*.pdf’, faAnyFile, FileInfo) = 0 then

                12. try

                13. for i := 0 to 20 do

                14. begin

                15.       P_List[i] := FileInfo.Name;

                16. if FindNext(FileInfo) <> 0 then

                17. Break;

                18. end;

                19. finally

                20.     FindClose(FileInfo);

                21. end;

                22. end;

                Won’t compile, complaining Error: Incompatible type for arg no. 1: Got «TRawbyteSearchRec», expected «QWord» at FindClose(FileInfo).

                That means the compiler is trying to call the Win32 API FindClose() function instead of the RTL’s SysUtils FindClose() function.  The Win32 API function takes a HANDLE as input, that is where the QWord is coming from (when you are compiling for 64bit).  You likely have the Windows unit after the SysUtils unit in your ‘uses’ clause, causing the Win32 API function to take priority.  Either swap the units around, or else quality which function you intended to call:

                1. if FindFirst(DataPath+‘*.log’,faAnyFile,FileInfo) = 0 then

                2. begin

                3. SysUtils.FindClose(FileInfo); // <— here

                4. end;

                I’ve checked that both projects are set to the same ‘bittness’ (actually tried both 32 and 64).

                Bitness has nothing to do with this.  It is a naming comflict.  Delphi has the same problem.

                In the second project, I need to go on to find other files (with a different extension) so assume that I need to call FindClose before doing so.

                You always have to call FindClose() regardless, or else you will leak OS resources.

                « Last Edit: June 13, 2017, 08:17:11 pm by Remy Lebeau »


                Logged


                …Error: Incompatible type for arg no. 1: Got «TRawbyteSearchRec», expected «QWord»[/color] at FindClose(FileInfo).

                Specify explicitly SysUtils.FindClose. In the second case, most likely you have the function Windows.FindClose.
                Additional. In the first example, you skip half of all files, because each FindNext retrieves one file at a time. Two calls FindNext (FileInfo) = 0 and FindNext (FileInfo) <> 0, but one addition of the file.
                There should be the following scheme:

                1. FoundFile := FindFirst(…, FileInfo) = 0;

                2. try

                3. while FoundFile do

                4. begin

                5. // Work with FileInfo

                6.     FoundFile := FindNext(FileInfo) = 0;

                7. end;

                8. finally

                9.   SysUtils.FindClose(FileInfo);

                10. end;

                @Remy Lebeau
                In FPC, unlike Delphi, FindClose should be called regardless of the success of FindFirst. See docs.


                Logged


                @Remy Lebeau
                In FPC, unlike Delphi, FindClose should be called regardless of the success of FindFirst. See docs.

                That’s not: unlike Delphi
                That’s always the case. Specifically under windows the handle won’t get released until program termination….
                Remy should know better.


                Logged

                I actually get compliments for being rude… (well, Dutch, but that is the same)


                In FPC, unlike Delphi, FindClose should be called regardless of the success of FindFirst. See docs.

                The statement in the doc is a little ambiguous to me.  Does it mean that FindClose() must always be called even if FindFirst() fails, or only if it succeeds?  Does FindFirst() always allocate memory that is then not freed if FindFirst() subsequently fails?  If so, why does it not free the memory before exiting?  That smells like a design bug to me.


                Logged


                In FPC, unlike Delphi, FindClose should be called regardless of the success of FindFirst. See docs.

                The statement in the doc is a little ambiguous to me.  Does it mean that FindClose() must always be called even if FindFirst() fails, or only if it succeeds?  Does FindFirst() always allocate memory that is then not freed if FindFirst() subsequently fails?  If so, why does it not free the memory before exiting?  That smells like a design bug to me.

                The best docs for that are on MSDN. But anyway, to answer your question: if the allocation of the handle fails, findclose is not necessary. Because there’s nothing to close… https://msdn.microsoft.com/en-us/library/windows/desktop/aa364413(v=vs.85).aspx
                ASerge was merely incomplete but essentially correct.
                So note that the same goes for Delphi.

                « Last Edit: June 13, 2017, 08:27:08 pm by Thaddy »


                Logged

                I actually get compliments for being rude… (well, Dutch, but that is the same)


                That’s not: unlike Delphi
                That’s always the case. Specifically under windows the handle won’t get released until program termination….
                Remy should know better.

                Actually, I do know better.  In Delphi, if FindFirst() fails, it calls FindClose() before exiting (and always has), thus any subsequent FindClose() in user code would be a no-op.  FindClose() in user code is only meaningful if FindFirst() succeeds.  I would expect FPC to have the same behavior, for compatibility when porting Delphi code to FPC.


                Logged


                The best docs for that are on MSDN. But anyway, to answer your question: if the allocation of the handle fails, findclose is not necessary. Because there’s nothing to close… https://msdn.microsoft.com/en-us/library/windows/desktop/aa364413(v=vs.85).aspx

                I understand that.  But at least in Delphi, FindFirst() does more than then call FindFirstFile() by itself.  It may ALSO call FindNextFile() (potentially more than once) to take the ExcludeAttr into account, so it may have to skip files before returning the first matching file. If THAT fails, FindFirst() calls FindClose() before exiting.  FindNext() also performs the same ExcludeAttr skipping loop, so it may have to call FindNextFile() more than once.  But, if that fails, FindNext() does not call FindClose() before exiting, it requires the caller to call it instead.

                I would expect the same from FPC.

                « Last Edit: June 13, 2017, 08:31:15 pm by Remy Lebeau »


                Logged


                Actually, I do know better.  In Delphi, if FindFirst() fails, it calls FindClose() before exiting (and always has), thus any subsequent FindClose() in user code would be a no-op.  FindClose() in user code is only meaningful if FindFirst() succeeds.  I would expect FPC to have the same behavior, for compatibility when porting Delphi code to FPC.

                So you rely on implementation detail? Anyway. In this case (but I will check it, because I am not convinced) this would work in most but not all cases:
                Because it does not check the fail reason and if findfirst fails because of a failing handle allocation that is sh*t code because there is nothing to close anyway???? >:D

                Agree?? O:-)


                Logged

                I actually get compliments for being rude… (well, Dutch, but that is the same)


                So you rely on implementation detail?

                Yes, because that is the most accurate way to know how something really works.  Documentation is not always accurate.

                Anyway. In this case (but I will check it, because I am not convinced) this would work in most but not all cases

                I assure you, it works the way I described.  I have Delphi’s RTL/VCL/FMX source code for almost all Delphi versions from Delphi 5 all the way up to 10.0 Seattle (I’m missing 1-4, 7-8, and 2005).  I looked at them before posting my replies here.

                If you look at the various Delphi implementations over the years, you can see that any failure inside of FindFirst() will call FindClose() before exiting if the search handle has been allocated.

                « Last Edit: June 13, 2017, 11:58:28 pm by Remy Lebeau »


                Logged


                Which is dumb >:( programming? Agree?? O:-) By now I have looked at the code (and in my own copies of D5, D7, D2006 and XE2). Since that is copyrighted. Plz edit your post.


                Logged

                I actually get compliments for being rude… (well, Dutch, but that is the same)


                According to FPC documentation, you should always call FindClose. This contradicts the general idea (also supported by Microsoft) that if there is an error in resource allocation, you do not need to release it. Delphi supports this concept within itself, ie. there it is correct to do, like you, call FindClose only after a successful FindFirst. Moreover, in earlier versions of Delphi there was a run-time error if there was an «extra» FindClose. Then they were safe from such a mistake, because many newcomers did not understand the concept.
                In FPC, there is no implementation for such idea, so you always need to call FindClose.


                Logged


                It seems I’m adept at stirring a Hornet’s Nest  ::)

                Many thanks to Remy for pointing out where my error lay — quite right about Windows being after SysUtils. I only added Windows when I needed to test for the internet being available and stupidly simply added it to the end of my Uses Clause — I hope that is a useful lesson learned  —  just never occurred to me  :-[

                Also thanks to ASerge and Remy for pointing out the inefficient loops — all now replaced.


                Logged

                FPC 3.0.0 — Lazarus 1.6 &
                FPC 3.2.2  — Lazarus 2.2.0 
                Win 7 Ult 64


                In FPC, there is no implementation for such idea, so you always need to call FindClose.

                Nope. Nonsense. You should just check on findfirst… on all platforms. I will put in a bug report. If findfirst fails, also on fpc, no need to call findclose.
                You do not understand the stupidity of the Delphi code…. But you are smart, You read what MSDN says…. The Delphi code does basically nothing in the most likely case. And circumvented that later by preventing a second call… That’s why… Now, you agree too O:-) O:-)

                Note this stupidity is not platform specific. It is stupid on ANY file handle.
                [edit]
                I put in the bug report against documentation.
                https://bugs.freepascal.org/view.php?id=32012

                « Last Edit: June 13, 2017, 11:16:00 pm by Thaddy »


                Logged

                I actually get compliments for being rude… (well, Dutch, but that is the same)


                If findfirst fails, also on fpc, no need to call findclose.

                NEED!

                1. program Project1;

                2. {$APPTYPE CONSOLE}

                3. uses Windows, SysUtils;

                4. function GetProcessHandleCount(hProcess: THandle;

                5.   out pdwHandleCount: DWORD): BOOL; stdcall; external kernel32;

                6. function HandleCount: DWORD;

                7. begin

                8. if not GetProcessHandleCount(GetCurrentProcess, Result) then

                9.     Result := 0;

                10. end;

                11. procedure ResourceLeak;

                12. var

                13.   R: TSearchRec;

                14. begin

                15. if FindFirst(‘c:\Windows\Fonts’, faDirectory, R) = 0 then

                16.     FindClose(R);

                17. end;

                18. procedure NoLeak;

                19. var

                20.   R: TSearchRec;

                21. begin

                22.   FindFirst(‘c:\Windows\Fonts’, faDirectory, R);

                23.   FindClose(R);

                24. end;

                25. var

                26.   i: Integer;

                27. begin

                28. Writeln(‘HandleCount: ‘, HandleCount);

                29. for i := 0 to 100 do

                30.     ResourceLeak;

                31. Writeln(‘HandleCount: ‘, HandleCount);

                32. for i := 0 to 100 do

                33.     NoLeak;

                34. Writeln(‘HandleCount: ‘, HandleCount);

                35. Readln;

                36. end.

                In Delphi no leak.


                Logged


                Понравилась статья? Поделить с друзьями:

                Интересное по теме:

              • Delphi assignfile ошибка
              • Defect acculading ошибка рено меган 2
              • Delphi 7 unable to rename delphi32 ошибка
              • Defect 200 рено премиум ошибка
              • Def1 ошибка на микроволновке

              • 0 0 голоса
                Рейтинг статьи
                Подписаться
                Уведомить о
                guest

                0 комментариев
                Старые
                Новые Популярные
                Межтекстовые Отзывы
                Посмотреть все комментарии