На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

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


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> как вернуть параметр из функции , как вернуть параметр из функции
    Здравствуйте! как вернуть, переслать, отправить параметр из функции?
    функция:
    ExpandedWrap disabled
       function LoadFile(FileName: TFileName):string;
      var
       MemStr: TMemoryStream;
       Title,s: String;
      begin
       MemStr:= TMemoryStream.Create;
       try
        MemStr.LoadFromFile(FileName);
        MemStr.Seek(0, soFromBeginning);
       // Title := ReadStreamStr( MemStr );
       finally
         MemStr.Free;
        end;
      end;

    кнопка :thanks:
    ExpandedWrap disabled
      procedure TForm1.Button1Click(Sender: TObject);
      begin
      LoadFile('test.txt');
      end;

    как сделать так: :blush:
    ExpandedWrap disabled
      procedure TForm1.Button1Click(Sender: TObject);
      begin
      LoadFile('test.txt');
       
      memo1.Lines.LoadFromStream(MemStr);
      и
      label1.caption:=MemStr.size;
      end;
        Если надо вернуть параметр, тогда используйте var или out
        ExpandedWrap disabled
          function LoadFile(FileName: TFileName; out MemStr: TMemoryStream):string;
          begin
            MemStr:= TMemoryStream.Create;
            try
              MemStr.LoadFromFile(FileName);
              MemStr.Seek(0, soFromBeginning);
              Result := ReadStreamStr(MemStr);
            except
              MemStr.FreeAndNil;
            end;
          end;
        Сообщение отредактировано: macomics -
          Цитата macomics @

          FreeAndNil может тогда уж? :huh:
            Цитата Rouse_ @
            FreeAndNil может тогда уж?
            Все равно. Он же ошибки не проверяет в коде. А так у него вылезет обращение к адресу $00000000 и будет долго тупить.
              Цитата leon2009 @
              Здравствуйте! как вернуть, переслать, отправить параметр из функции?


              Могу ошибаться, но функция LoadFile не присваивает ничего переменной Result - соответсвенно, ничего не будет возвращено наружу

              Далее: MemStr является локальной переменной функции, но в обработчиках формы (второй вариант) к ней пытаются достучаться

              Третье: что если файл размером N гигабайт? Попытка прочитать его весь сразу никогда не сможет быть успешной.
                macomicsдык а так у него вылезет AV по рандомному адресу и тупить придется с более хитрым числом :)
                По правильному делать надо так:

                ExpandedWrap disabled
                    except
                      MemStr.FreeAndNil;
                      raise;
                    end;
                  Цитата Rouse_ @
                  По правильному делать надо так:
                  По правильному не стоит вообще злоупотреблять try except/finally end. У него это все описано в функции. Стоит просто вернуть статус неудачной загрузки файла в качестве результата работы функции, а не лепить кучу вложенных блоков try.
                    Так работает:
                    ExpandedWrap disabled
                      function LoadFile(FileName: TFileName):TMemoryStream;
                      var
                       MemStr: TMemoryStream;
                       Title,s: String;
                      begin
                       Result:= TMemoryStream.Create;
                       try
                        Result.LoadFromFile(FileName);
                        Result.Seek(0, soFromBeginning);
                       finally
                         //Result.Free;
                        end;
                      end;
                       
                      procedure TForm1.Button1Click(Sender: TObject);
                      begin
                        memo1.Lines.LoadFromStream(LoadFile('c:\Install.log'));
                      end;


                    Добавлено
                    или вот так:
                    ExpandedWrap disabled
                      Type
                       TR = record
                          MemStr:TMemoryStream;
                          Size:int64;
                        end;
                       
                       
                      function LoadFile(FileName: TFileName):TR;
                      begin
                       Result.MemStr:= TMemoryStream.Create;
                       try
                        Result.MemStr.LoadFromFile(FileName);
                        Result.MemStr.Seek(0, soFromBeginning);
                        Result.size:=Result.MemStr.Size;
                       finally
                        end;
                      end;
                       
                      procedure TForm1.Button1Click(Sender: TObject);
                      Var
                        TR1:TR;
                      begin
                        TR1:=LoadFile('c:\Install.log');
                        memo1.Lines.LoadFromStream(TR1.MemStr);
                        label1.caption:=IntToStr(TR1.size);
                      end;
                      А вообще проще memo скормить файл и получить длину через memo.GetTextLen чем городить огород с функцией которая должна в памяти держать файл
                        Кстати а в моем примере будет утечка памяти если многократно вызывать функцию где есть TStream.Create и не освобождать ее?
                        Или нужно перед созданием проверять что она существует и удалять ее через free? Или при create она просто перепишется?
                          Если вы не вызовите TR1.MemStr.Free тогда будет утечка памяти.

                          Это легко проверить если взять вашу программу и файл размером длиной ок. 64-512 кб и загружать его несколько раз. При это открыв Диспетчер задач вы наглядно увидите увеличение объема памяти у вашей программы.
                          Сообщение отредактировано: macomics -
                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script execution time: 0,0343 ]   [ 16 queries used ]   [ Generated: 20.04.24, 06:23 GMT ]