在 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
函数,有什么方法可以做到这一点?
我会注意:
DllMain
,因此也不能使用任何 C++ 全局静态析构函数。
- 在 kernel32/ntdll 或共享的 MS CRT 中是否有任何其他回调机制来实现这一点?
- 还有其他模式可以使这个用例起作用吗?
正确的方法是 DLL_1 中的显式 Uninitialize 函数。
但是,如果您不能这样做,您可以通过启动辅助线程来为您卸载来解决此问题。如果您想安全起见,请在加载 DLL_x 的同时启动线程并让它等待事件对象。 (不过,为了记录,从 DllMain
启动线程通常被认为是安全的,只要您尊重它在 DllMain
退出之前不会启动的事实。)
显然,辅助线程的代码不能在DLL_1中。如果你可以修改 DLL_x 你可以把它放在那里。如果没有,您将需要一个帮助程序 DLL。在任何一种情况下,包含辅助线程代码的 DLL 都可以使用 FreeLibraryAndExitThread 函数安全地自行卸载。
我们遇到了一个案例,其中最好的解决方案是放置 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
函数,有什么方法可以做到这一点?
我会注意:
DllMain
,因此也不能使用任何 C++ 全局静态析构函数。- 在 kernel32/ntdll 或共享的 MS CRT 中是否有任何其他回调机制来实现这一点?
- 还有其他模式可以使这个用例起作用吗?
正确的方法是 DLL_1 中的显式 Uninitialize 函数。
但是,如果您不能这样做,您可以通过启动辅助线程来为您卸载来解决此问题。如果您想安全起见,请在加载 DLL_x 的同时启动线程并让它等待事件对象。 (不过,为了记录,从 DllMain
启动线程通常被认为是安全的,只要您尊重它在 DllMain
退出之前不会启动的事实。)
显然,辅助线程的代码不能在DLL_1中。如果你可以修改 DLL_x 你可以把它放在那里。如果没有,您将需要一个帮助程序 DLL。在任何一种情况下,包含辅助线程代码的 DLL 都可以使用 FreeLibraryAndExitThread 函数安全地自行卸载。