Delphiに、単一のグローバルオブジェクトを提供する(オプションがある)ユニットがあります。
var
InternalThemeParkServices: TThemeParkServices;
function ThemeParkServices: TThemeParkServices;
begin
if InternalThemeParkServices= nil then
InternalThemeParkServices := TThemeParkServices.Create();
Result := InternalThemeParkServices ;
end;
...
initialization
finalization
FreeAndNil(InternalThemeServices);
end.
そして、私はプロセスのシャットダウン中に自分自身を破壊します。
注:別のコードバリアントは次のとおりです。
var InternalThemeParkServices: IThemeParkServices; function ThemeParkServices: TThemeParkServices; begin if InternalThemeParkServices= nil then InternalThemeParkServices := TThemeParkServices.Create(); Result := InternalThemeParkServices ; end;
プログラムのシャットダウン中に参照カウントがゼロになると、インターフェイス変数が暗黙的に破棄される場合
オブジェクトが使用されなくなったとき(つまり、オブジェクトの実行中destructor
)、さまざまなWinAPI関数を呼び出します。
問題は、誰かがDLL(私が制御できないもの)から私のクラスを使用する場合、次の間に何かが呼び出されることです。
finalization
Delphiの道徳的同等物ですDLL_PROCESS_DETACH
。プロセスが終了している間、私がしてはいけないことはたくさんあります(例)。 DLL_PROCESS_DETACH
CoCreateInstance
私はEmbarcaderoが使用していることを知っています:
initialization
if not IsLibrary then
begin
...
コードを次のように変更して、適応できる可能性があります。
var
InternalThemeParkServices: IThemeParkServices;
(暗黙のクリーンアップを使用)、次のように:
var
InternalThemeParkServices: IThemeParkServices;
...
finalization
if IsLibrary then
Pointer(InternalThemeParkServices) := nil; //defeat reference counting and let the object leak
end;
そしてそれを漏らします。
しかし、これは最高の解決策ですか?私のコードを実行しているdllがアンロードされた場合(ただし、プロセスのシャットダウン中ではない)、メモリがリークすることを意味すると思います。dllがアタッチおよびデタッチされている場合、毎回リークします。
私が本当に望んでいるのは、Delphiが/の前にfinalization
ブロックを実行することです。これは可能ですか? ExitProcess
DllMain(DLL_PROCESS_DETACH)
ボーナスチャッター
@paはDelphiアプリケーションのシャットダウンスキームを解読しました:
シャットダウンの階層は次のとおりです。
Application.Terminate() performs some unidentified housekeeping of application calls Halt() Halt() calls ExitProc if set alerts the user in case of runtime error get rid of PackageLoad call contexts that might be pending finalize all units clear all exception handlers call ExitprocessProc if set and finally, call ExitProcess() from 'kernel32.dll' ExitProcess() unloads all DLLs uses TerminateProcess() to kill the process
-の呼び出し後にDLLがアンロードされますExitProcess
。これは、Windowsがそれを実行するためです。