我们遇到的情况是,FreeLibrary
/ (unknown client dll or exe) links dynamically or statically to ->
-> DLL_1, loads dynamically -> DLL_x
将DllMain
电话放入我们的最佳解决方案。
当然,你must not do that:
从DllMain调用FreeLibrary是不安全的。
用例是我们遇到这样的情况:
LoadLibrary
DLL_1应该透明地加载DLL_x。它的客户端代码,它应该动态加载DLL_x。现在,可以懒惰地加载,因此DLL_PROCESS_ATTACH
调用不需要驻留在DLL_1的DLL_1/Uninitialize
部分。
但是一旦客户端完成了DLL_1,当从进程中卸载DLL_1之前/之后,它也应该卸载(== FreeLibrary)DLL_x。
如果没有必须由客户调用的明确DllMain
函数,有没有办法做到这一点?
我会注意到:
<system.diagnostics>
<sharedListeners>
<add name="AzureDriveTraceListener" type="Microsoft.WindowsAzure.WebSites.Diagnostics.AzureDriveTraceListener, Microsoft.WindowsAzure.WebSites.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</sharedListeners>
<sources>
<source name="TraceSourceLogging" switchName="TestSwitch" switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add name="AzureDriveTraceListener"/>
</listeners>
</source>
</sources>
<switches>
<add name="TestSwitch" value="Verbose" />
</switches>
</system.diagnostics>
,因此也不能使用任何C ++全局静态析构函数。答案 0 :(得分:1)
正确的方法是DLL_1中的显式Uninitialize函数。
但是,如果你不能这样做,你可以通过启动一个帮助程序线程为你卸载来解决这个问题。如果要安全地播放它,请在加载DLL_x的同时启动该线程并让它等待事件对象。 (但是,对于记录,从DllMain
发起一个帖子通常被认为是安全的,只要你尊重它在DllMain
退出之前就不会启动的事实。)
显然,帮助程序线程的代码不能在DLL_1中。如果你可以修改DLL_x,你可以把它放在那里。如果没有,您将需要一个帮助DLL。在任何一种情况下,包含帮助程序线程代码的DLL都可以使用FreeLibraryAndExitThread函数安全地自行卸载。