安全的地方把不安全的DLL清理代码在Windows上?

我们遇到了一个情况,那就是将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 ++全局静态析构函数。
  • 在kernel32 / ntdll中,还是在共享的MS CRT中,是否还有其他callback机制来实现这一点?
  • 还有其他的模式,使这个用例工作?

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

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

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