我在 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
是 的德尔福道德等价物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)
奖金喋喋不休
关机的层次结构如下
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 是这样做的。