Не совсем. UnloadPackage дёргает FinalizePackage и сразу выгружает библиотеку из памяти (FreeLibrary). После этого (если я правильно всё понимаю) деструктор некоего объекта уже выгруженной библиотеки дёрнуть просто не получится. Т.е. да, finalization/class-destructor выполнится раньше деструктора, но деструктор вообще не отработает - будет утечка памяти.
Я про другой случай, всё в рамках single-exe, и деструктор вызывается корректно. Подскажу: такое можно получить, когда необходимо сигнализировать об аварийном завершении приложения.
Согласен, деструктор не отработает, т.к. VMT класса будет уже не доступна, а компилятор заставляет туда лезть даже когда деструктор не переопределен =( Можно конечно пропатчить указатель на класс инстанса, но это уже другая история =)
а так, с подсказкой ;-) очевидно следующее: program ConsHalt; {$APPTYPE CONSOLE} {$I-}
type TMyClass = class public class destructor CD; destructor Destroy; override; end;
destructor TMyClass.Destroy; begin WriteLn('instance destructor'); ReadLn; inherited; end;
class destructor TMyClass.CD; begin WriteLn('class destructor'); end;
procedure ExitP(); var Obj: TMyClass; begin Obj := TMyClass.Create; Obj.Free; end;
Примерно так, да. Я на эту проблему наткнулся, когда делал Halt из OnCreate датамодуля (или формы - не важно, один эффект). Т.е. вот вроде бы нормальная ситуация - создаю датамодуль (ещё до создания каких-либо форм), он делает проверки, если что-то не устроило - Halt(X). Ан нет, так нельзя для VCL-приложения. Надо делать ExitCode := X и дальше Application.Terminate + Exit Ну или Abort/своё_исключение с обработкой в dpr-файле.
6 коммент.:
Динамические пакеты? UnloadPackage?
Не совсем. UnloadPackage дёргает FinalizePackage и сразу выгружает библиотеку из памяти (FreeLibrary). После этого (если я правильно всё понимаю) деструктор некоего объекта уже выгруженной библиотеки дёрнуть просто не получится.
Т.е. да, finalization/class-destructor выполнится раньше деструктора, но деструктор вообще не отработает - будет утечка памяти.
Я про другой случай, всё в рамках single-exe, и деструктор вызывается корректно. Подскажу: такое можно получить, когда необходимо сигнализировать об аварийном завершении приложения.
Согласен, деструктор не отработает, т.к. VMT класса будет уже не доступна, а компилятор заставляет туда лезть даже когда деструктор не переопределен =( Можно конечно пропатчить указатель на класс инстанса, но это уже другая история =)
а так, с подсказкой ;-) очевидно следующее:
program ConsHalt;
{$APPTYPE CONSOLE}
{$I-}
type
TMyClass = class
public
class destructor CD;
destructor Destroy; override;
end;
destructor TMyClass.Destroy;
begin
WriteLn('instance destructor');
ReadLn;
inherited;
end;
class destructor TMyClass.CD;
begin
WriteLn('class destructor');
end;
procedure ExitP();
var
Obj: TMyClass;
begin
Obj := TMyClass.Create;
Obj.Free;
end;
begin
ExitProcessProc := ExitP;
Halt;
end.
выдает
class destructor
instance destructor
Примерно так, да.
Я на эту проблему наткнулся, когда делал Halt из OnCreate датамодуля (или формы - не важно, один эффект). Т.е. вот вроде бы нормальная ситуация - создаю датамодуль (ещё до создания каких-либо форм), он делает проверки, если что-то не устроило - Halt(X). Ан нет, так нельзя для VCL-приложения. Надо делать ExitCode := X и дальше Application.Terminate + Exit
Ну или Abort/своё_исключение с обработкой в dpr-файле.
ExitProcess(X) в помощь, если не нужно ничего "убирать" за собой ;-)
Так ExitProcess как раз и дёргается Halt'ом и приводит к эффекту в задачке.
Отправить комментарий