【问题标题】:Delphi DllMain DLL_PROCESS_DETACH called before DLL_PROCESS_ATTACHDelphi DllMain DLL_PROCESS_DETACH 在 DLL_PROCESS_ATTACH 之前调用
【发布时间】:2012-04-30 00:51:48
【问题描述】:

我在处理用 Delphi 编写的 DLL 时遇到了很多麻烦。我在库中使用以下代码设置了一个 DllMain 函数:

begin
  DllProc := DllMain;
end.

我的DllMain 程序如下所示:

procedure DllMain(reason: Integer);
begin
  if reason = DLL_PROCESS_DETACH then
    OutputDebugString('DLL PROCESS DETACH')
  else if reason = DLL_PROCESS_ATTACH then
    OutputDebugString('DLL PROCESS ATTACH')
  else if reason = DLL_THREAD_ATTACH then
    OutputDebugString('DLL THREAD ATTACH')
  else if reason = DLL_THREAD_DETACH then
    OutputDebugString('DLL THREAD DETACH')
  else
    OutputDebugString('DllMain');
end;

我发现 DETACH 似乎在调用 ATTACH 之前被调用者(我无法控制)调用(两次?!)。这甚至可能吗,还是我误解了这应该如何工作?我的期望是每个 ATTACH 调用都会得到匹配的 DETACH 调用,但事实并非如此。

这是怎么回事?!

【问题讨论】:

    标签: windows delphi dll


    【解决方案1】:

    不幸的是,当您在 dll 代码中执行 begin 时,操作系统已经在您的库中调用了 DllMain。所以当你的DllProc := DllMain; 语句执行时已经太晚了。当 dll 附加到进程时,Delphi 编译器不允许执行用户代码。建议的解决方法(如果您可以称之为解决方法)是在单元初始化部分或库代码中自己调用您自己的 DllMain 函数:

    begin
      DllProc := DllMain;
      DllMain(DLL_PROCESS_ATTACH);
    end;
    

    relevant documentation:

    注意:只有当 DLL 的初始化代码调用过程并指定 DLL_PROCESS_ATTACH 作为参数时,DLL_PROCESS_ATTACH 才会传递给过程。

    【讨论】:

    • 嗯...我希望这将是我所有问题的解决方案,但是这些额外的知识(虽然是真实的并且回答了我的问题)还没有解决我的问题。看起来我将不得不创建另一个问题:)。感谢您的帮助!
    • 你不明白什么。这一切都在这个问题中。在您的代码可以执行之前发生的唯一 DllMain 调用是针对DLL_PROCESS_ATTACH。因此,您只需按照 Sertac 所说的方式编写即可。
    • 不,这很清楚。我理解它并且可以实现它。但是,它揭示了我的更大问题的答案(我希望与此有关)实际上与此问题无关。所以搜索继续!
    【解决方案2】:

    我发现 DETACH 似乎在 ATTACH 被调用之前被调用者(我无法控制)调用(两次?!)。

    根据 Petzold 的“Programming Windows 5th edition”。
    DLL_PROCESS_ATTACH 在应用程序启动时被调用,
    DLL_THREAD_ATTACH 在附加应用程序内的新线程启动时被调用。
    DLL_PROCESS_DETACH当附加到您的应用程序的应用程序退出时调用。
    DLL_THREAD_DETACH 当附加应用程序内的线程退出时调用。

    请注意,DLL_THREAD_DETACH 可以在没有对应的较早 DLL_THREAD_ATTACH 的情况下被调用。
    这发生在线程在应用程序链接到 dll 之前启动时。
    这主要发生在应用程序使用LoadLibrary 手动加载dll 而不是在编译时静态链接时。

    【讨论】:

    • 我不明白。你的意思是没有进程的线程?并且“LoadLibrary”不会导致“DLL_PROCESS_ATTACH”?
    • 这似乎无法解释为什么DLL_PROCESS_DETACH 会发生多次。
    猜你喜欢
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多