在 Windows 上放置不安全 DLL 清理代码的安全位置?

Safe place to put unsafe DLL cleanup code on Windows?

我们遇到了一个案例,其中最好的解决方案是放置 FreeLibrary call into DllMain / DLL_PROCESS_DETACH.

当然,你 must not do that:

It is not safe to call FreeLibrary from DllMain.

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

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

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

DLL_PROCESS_ATTACH 部分

但是一旦客户端完成 DLL_1,when/before DLL_1 从进程中卸载,它也应该卸载 (== FreeLibrary) DLL_x.

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

我会注意:

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

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

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