Delphi DLL 未卸载,可能是由于仍在分配的 GDI

标签 delphi dll delphi-2007

我们编写了一个 DLL 来执行所有打印功能。它允许我们进行打印预览、打印以及生成 PDF。

我们现在对该 DLL 有特定的使用模式,之后该 DLL 无法正确卸载。后果是当我们退出主程序时,它消失但并没有终止,我们必须手动杀死该进程。

我认为罪魁祸首是某些 GDI 资源没有被正确“关闭”(当我这么说时,我是出于对 GDI 的无知而说的)。我们并不直接处理GDI资源,而是在我们使用各种Delphi组件时,GDI资源为我们使用。

有关如何查找和解决此类问题的任何提示?我们使用 GDIView 来确认在尝试终止程序后仍然保留了一些 GID 资源,但我不知道如何将这些 Windows/内核句柄与底层 Delphi 代码关联起来。我可以在程序执行期间的不同时间提供 GIDView 列表。

谢谢!

乔恩(德尔福 2007)


我回复了提出的建议,但没有人回复我的回复。最终,我放弃了。我最终编写了一个自杀例程,它不仅杀死了我自己的进程,还杀死了所有其他同名的进程,作为解决问题的方法。可笑的矫枉过正,但我​​似乎别无选择。我正在使用我在某处找到的免费软件 ProcessInfo 工具。

procedure KillNamedProcesses(pName : String);
// used to clean up programs that hang as a result of DLLs not unloading
   var
      ProcessInfo : TProcessInfo;
      ProcessName : String;
      i : INTEGER;
      currentPID : cardinal;
   BEGIN
   currentPID := GetCurrentProcessID;
   pName := UpperCase(pName);
   ProcessInfo := TProcessInfo.Create(nil);

   // kill all old processes (not our process)
   for i := 0 to ProcessInfo.RunningProcesses.Count - 1 do begin
      ProcessName := ProcessInfo.RunningProcesses[i].ExeFile;
      IF (UpperCase(ProcessName) <> pName) THEN CONTINUE;
      IF (currentPID <> ProcessInfo.RunningProcesses[i].ProcessID) then
         ProcessInfo.RunningProcesses[i].TerminateProcess;
      END;
   // kill the last one (ourselves)
   for i := 0 to ProcessInfo.RunningProcesses.Count - 1 do begin
      ProcessName := ProcessInfo.RunningProcesses[i].ExeFile;
      IF (UpperCase(ProcessName) <> pName) THEN CONTINUE;
      ProcessInfo.RunningProcesses[i].TerminateProcess;
      END;
   ProcessInfo.Free;
   END; // KillNamedProcess

最佳答案

您无需返回 GDI 资源即可关闭进程。当然,您应该归还它们,但这不会阻止您终止。听起来很像 DLL 卸载时出现死锁。由于您的 DLL 无法卸载,那么您自然无法释放所有 GDI 资源。

调试此问题将涉及调试死锁。对此提供一般性建议相当困难,不幸的是您使用的是较旧且功能较弱的 Delphi 版本。现代 Delphi 调试器支持等待链遍历,使调试死锁变得相当简单。我想如果我是你,当你的应用程序处于死锁状态时,我会进行一些事后调试。我会查看所有线程的堆栈跟踪,并使用它来定位无限期阻塞的内容。当程序处于死锁状态时,使用 Process Explorer 和 map2dbg 获取有意义的堆栈跟踪。

关于Delphi DLL 未卸载,可能是由于仍在分配的 GDI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10343611/

相关文章:

Delphi XE2 VCL 样式未正确绘制 TabSheets

delphi - 加载 Jpg/Gif/Bitmap 并转换为 Bitmap

google-chrome - 为什么我在 ClickOnce 部署后突然在 Chrome 中收到 "Not commonly downloaded"警告?

delphi - Delphi VCL 拖放中的错误?

Delphi 2007 和 Logitech 网络摄像头驱动程序

delphi - 如何关闭 idHTTPServer 上的所有连接?

multithreading - 在没有 MyThread.Terminate 的情况下终止线程

python - 从python ctypes中的c++ dll传递 vector

c++ - Qt 快速 2 : Creating and adding a shared library

delphi - 如何批量将 bdsproj 转换为 dproj?