我们遇到了一个情况,那就是将FreeLibrary
调用放到DllMain
/ DLL_PROCESS_DETACH
是最好的解决scheme。
当然,你不能这样做 :
从DllMain调用FreeLibrary是不安全的。
用例是我们有这样的情况:
(unknown client dll or exe) links dynamically or statically to -> -> DLL_1, loads dynamically -> DLL_x
DLL_1应该透明地加载DLL_x。 到它的客户端代码,它应该dynamic加载DLL_x。 现在,加载可以被懒惰地完成,所以LoadLibrary
调用不需要驻留在DLL_1的DLL_PROCESS_ATTACH
部分。
但是,一旦客户端完成了DLL_1,在DLL_1从进程中卸载之前,它也应该卸载(== FreeLibrary)DLL_x。
有没有办法做到这一点,而不必显式的DLL_1/Uninitialize
函数,必须由客户端调用?
我会注意到:
DllMain
,因此也不能使用任何C ++全局静态析构函数。 正确的方法是在DLL_1中显式的Uninitialize函数。
但是,如果你不能这样做,你可以通过启动一个辅助线程来解决这个问题。 如果你想安全地玩,请在加载DLL_x的同时启动线程并让它等待一个事件对象。 (但是,对于记录,只要您尊重在DllMain
退出之前不会启动的事实,通常认为从DllMain
启动一个线程是安全的。)
显然,帮助线程的代码不能在DLL_1中。 如果你可以修改DLL_x,你可以把它放在那里。 如果没有,你需要一个辅助DLL。 在任何一种情况下,包含帮助程序线程代码的DLL都可以使用FreeLibraryAndExitThread函数安全地自卸载。