【发布时间】:2020-06-12 10:28:20
【问题描述】:
我有一个调用 DLL 的 Delphi 代码。 DLL 是动态链接的。
在我的代码的开头,我通过
启动/打开 DLLDllHandle:= LoadLibrary(DllFileName);
- 如果 DLL 文件不存在,我会得到一个
DLLHandle=0,这很好。我可以在主程序中继续我的下一行。 - 如果 DLL 文件存在并正确初始化,我会得到一个
non-zero DLLHandle,这也很好。
但是,DLL 内部时不时会出现问题,这意味着文件存在但 DLL 没有响应。 所以我的主要应用程序挂起。
为了避免这种情况,我研究了多线程。
我的主程序有一个新类型 TMyThread 继承自 TThread 并覆盖 Create, Destroy, Execute。
我的主程序即时创建一个新线程 (ChildThread)。 ChildThread 的Execute 方法正在调用上面提到的LoadLibrary。
通过这样做,我可以继续我的主程序并稍等片刻,看看ChildThread 是否返回一个非零的 DLL 句柄。
如果 ChildThread 中的 DLLhandle 在几秒钟后仍然为零,我想终止线程并释放 DLL 并重试。
进一步调查我可以看到 Delphi IDE 中的线程列表。最初我的主程序下有 4 个线程。当我创建 ChildTread 时,会出现一个新的。几秒钟后(当调用 Execute 并在 ChildTread 中调用 loadlibrary 时)又出现了两个线程。我猜主 DLL 正在调用其他线程。
在这个阶段,我无法访问 ChildTread,因此我无法在 Execute 方法中使用 while 循环来查看它是否已终止并退出线程。因为该线程中的实际代码已经挂在执行中。
问题:
ChildTread 挂起,但我的主程序仍在继续。我想从我的主程序中杀死 ChildThread(可能是它启动的所有其他线程)并重试
DllHandle:= LoadLibrary(DllFileName);
【问题讨论】:
-
这是错误的解决方案。您不能在单个进程中完成这项工作。您需要将其移至单独的进程中。您需要通过流程获得的隔离。
-
有没有办法在 Delphi 中做到这一点?
-
是的,但这不是微不足道的。一种选择是进程外 COM 服务器。这会照顾所有的 IPC。如果是我,我会修复 DLL(或者可能是您使用它的方式)。
-
我不明白为什么杀死我创建的线程(或简单的函数调用)如此难以杀死。所以在 Delphi 中我知道哪些线程 ID 应该被杀死但不能被杀死?。
-
"我不明白为什么杀死我创建的线程(或简单的函数调用)是如此难以杀死" --- 因为通常你不会简单地"杀死”线程。
标签: multithreading delphi dll loadlibrary