9

我在处理用 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 调用,但情况似乎并非如此。

这是怎么回事?!

4

2 回答 2

12

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

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

相关文件

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

于 2012-04-30T01:19:05.893 回答
-1

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

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

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

于 2014-11-05T15:02:02.847 回答