1

我们遇到了一个案例,将FreeLibrary呼叫放入DllMain/将是我们的最佳解决方案DLL_PROCESS_DETACH

当然,你不能这样做

从 DllMain 调用 FreeLibrary 是不安全的。

用例是我们有这样的情况:

(unknown client dll or exe) links dynamically or statically to -> 
      -> DLL_1, loads dynamically -> DLL_x

DLL_1 应该透明地加载 DLL_x。到它的客户端代码,它应该动态加载 DLL_x。现在,加载可以延迟完成,因此LoadLibrary调用不必驻留在DLL_PROCESS_ATTACHDLL_1 的部分。

但是一旦客户端完成了 DLL_1,当 DLL_1 从进程中卸载时/之前,它也应该卸载 (== FreeLibrary) DLL_x。

DLL_1/Uninitialize如果没有客户端必须调用的显式函数,有什么方法可以做到这一点?

我会注意:

  • DllMain,因此也不能使用任何 C++ 全局静态析构函数。
  • kernel32/ntdll 或者共享的 MS CRT 中是否有任何其他回调机制来实现这一点?
  • 是否有其他模式可以使这个用例工作?
4

1 回答 1

1

正确的方法是 DLL_1 中的显式 Uninitialize 函数。

但是,如果您不能这样做,您可以通过启动一个帮助线程为您执行卸载来解决该问题。如果您想安全起见,请在加载 DLL_x 的同时启动线程并让它等待事件对象。DllMain(不过,作为记录,只要您尊重它DllMain在退出之前不会启动的事实,通常认为启动线程是安全的。)

显然,辅助线程的代码不能在 DLL_1 中。如果你可以修改 DLL_x 你可以把它放在那里。如果没有,您将需要一个帮助 DLL。在任何一种情况下,包含帮助线程代码的 DLL 都可以使用FreeLibraryAndExitThread函数安全地自行卸载。

于 2017-07-19T23:25:21.157 回答