加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何在调用ExitProcess之后判断我是否在DLL_PROCESS_D

发布时间:2020-12-15 09:34:01 所属栏目:大数据 来源:网络整理
导读:我在Delphi中有一个单元(可以选择)提供一个全局对象: var InternalThemeParkServices: TThemeParkServices;function ThemeParkServices: TThemeParkServices;begin if InternalThemeParkServices= nil then InternalThemeParkServices := TThemeParkService
我在Delphi中有一个单元(可以选择)提供一个全局对象:

var
   InternalThemeParkServices: TThemeParkServices;

function ThemeParkServices: TThemeParkServices;
begin
   if InternalThemeParkServices= nil then
      InternalThemeParkServices := TThemeParkServices.Create();
   Result := InternalThemeParkServices ;
end;

...

initialization
finalization
   FreeAndNil(InternalThemeServices);
end.

我在进程关闭期间摧毁了自己.

Note: Another code variant is:

06001

Where the interface variable is implicitly destroyed when it’s
reference count goes to zero during program shutdown

当我的对象不再使用时(即在析构函数中),我调用各种WinAPI函数.

问题是如果有人使用我的DLL中的类(我无法控制的东西),那么在以下期间调用的任何东西:

finalization

是德尔福道德等同于DLL_PROCESS_DETACH. There是all kinds of things i should not be doing during DLL_PROCESS_DETACH 070??04(例如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在ExitProcess / DllMain(DLL_PROCESS_DETACH)之前运行它的终结块.这可能吗?

奖金Chatter

@pa破译the Delphi application shutdown scheme:

The hierarchy of shutdown is as follows

06006

在调用ExitProcess之后卸载DLL – 因为Windows是执行它的人.

解决方法

要在调用ExitProcess之后判断您是否在DLL_PROCESS_DETACH期间被调用,您可以为库编写初始化代码,以便在从主程序调用FreeLibrary时执行代码.如果已经调用了ExitProcess,则’lpReserved’参数将为’1′,否则为’0’:

..
var
  SaveDllProcEx: TDllProcEx;

procedure DllMainEx(Reason: Integer; Reserved: Integer);
begin
  if (Reason = DLL_PROCESS_DETACH) and (Reserved = 0) then
    // Main app is still running,cleanup.

  if Assigned(SaveDllProcEx) then
    SaveDllProcEx(Reason,Reserved);
end;

initialization

if IsLibrary then begin
  SaveDllProcEx := DllProcEx;
  DllProcEx := @DllMainEx;
end;

从DllMain entry point开始:

The lpReserved parameter indicates whether the DLL is being unloaded as a result of a FreeLibrary call,a failure to load,or process termination.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读