На главную Наши проекты:
Журнал   ·   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_
  
> Отмена создания объекта
    При создании объекта нужно предусмотреть ситуацию ошибки (конструктор проверяет некоторые системные настройки и принимает решение - создавать объект или нет), т.е. чтобы Create вернул nil или сгенерировал исключение. Как это сделать?
      Ну и кидай исключение, в чем проблема-то?
        Цитата
        If an exception is raised during execution of a constructor that was invoked on a class reference, the Destroy destructor is automatically called to destroy the unfinished object.


        ExpandedWrap disabled
          constructor TBase.Create;
          begin
          raise Exception.Create('Missing envirement') at @TBase.Create;
          end;
           
          ...
          var tmp:TBase;
          procedure TForm1.Button1Click(Sender: TObject);
          begin
           try
           tmp:=TBase.Create;
           except
             on E: Exception do
              tmp:=nil;
           end;
          end;
          Ok, а как просто nil вернуть без генерации исключения?
            Jin X
            Просто никак.
            Всякая конструкция вида self:=nil; приведёт к ошибке в автоконструкторе и последний вызывает исключение.
            Можно попробовать хаком изменить адрес возврата на свою функцию, тем самым обойти автоконструктор.
              Разве что фабрикой
              ExpandedWrap disabled
                function CreateObj(aClass: TClass): TObject;
                begin
                  try
                    Result := aClass.Create;
                  except
                    Result := nil;
                  end;
                end;

              Но с параметрами конструктора придется что-то придумывать.

              Ну или через asm регистры зачистить. Но это жестко
                Fr0sT, не факт, что это прокатит, т.к.
                ExpandedWrap disabled
                  class function TMyObject1.NewInstance: TObject;
                  begin
                    Result := nil;
                  end;
                Работает, но Create при возврате выдаёт ошибку...
                  Цитата Jin X @
                  не факт, что это прокатит

                  То, что ты привел, никак не связано с моим предположением
                    Ну ок.
                    Вот такая конструкция работает:
                    ExpandedWrap disabled
                      {$APPTYPE CONSOLE}
                      type
                        TObj = class
                          constructor Create;
                        end;
                       
                      constructor TObj.Create;
                      asm
                      //  int 3
                        xor eax,eax
                        db 0EBh,9  // jmp $+2+9
                      end;
                       
                      var Obj: TObj;
                      begin
                        Obj := TObj.Create;
                        WriteLn(Integer(Obj))
                      end.

                    Но! Есть 2 нюанса:

                    1. Create после выполнения основного кода делает:
                    ExpandedWrap disabled
                        test dl,dl
                        je @@ret
                        call Call_AfterDestruction  // вот здесь как раз и возникало исключение в варианте с NewInstance
                        pop dword fs:[0]
                        add esp,0Ch
                      @@ret:
                        ret
                    Зачем проверяется dl и что там должно быть - х/з. Кто-нибудь знает?
                    Может, где-то оно и нужно и там будет креш.

                    2. dcc64 (и XE2, и Tokyo) не компилируют конструктор, написанный на ассемблере, выдают Fatal: F2084 Internal Error: AV00511A6C-R00000001-0. Так что такой вариант не будет работать в 64 битах... обидно
                      Цитата Jin X @
                      Зачем проверяется dl и что там должно быть - х/з. Кто-нибудь знает?

                      См. справку. Конструкторы и деструкторы имеют дополнительный булевский параметр (флаг), передаваемый через регистр dl (при register convention). Значение true=1 означает вызов конструктора через ссылку на класс для создания нового экземпляра класса. Значение false=0 передается при вызове конструктора через экземпляр класса как обычного метода инициализации (например при вызове inherited Create).
                        Спасибо за инфу. Так что, приведённый мной пример вообще неуниверсален. При разном содержимом Create будет работать по-разному, нужно подгонять под каждый случай.
                        В целом, я так подумал, что возвращать nil вообще нехорошо, лучше генерить исключение :D
                          Цитата Jin X @
                          В целом, я так подумал, что возвращать nil вообще нехорошо, лучше генерить исключение

                          Возвращение блудного сына к разумному решению))
                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                          0 пользователей:


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