我有一个第三方DLL,当试图从我的本地C应用程序卸载它时引发一个未处理的exception。 这会导致调用FreeLibrary失败,并将模块保留在我的进程中。
有没有任何select来强制卸载图书馆?
FreeLibrary呼叫时你做什么?
当使用加载时间dynamic链接时,这是令人讨厌的,但最终应用程序被操作系统拆除。 使用运行时dynamic链接时出现问题。 我加载这个DLL,使用它,然后在某些情况下,我需要从我的进程的虚拟地址空间卸载它,然后继续运行。 当我在第三方库上调用FreeLibrary时,它会执行一些清理工作(即在调用DLL_PROCESS_DETACH时在DllMain中 )。 虽然它正在进行清理,但会导致抛出exception,导致它无法处理,并以FreeLibrary的未处理exceptionforms出现。 这导致调用失败,模块保持加载状态。
我已经把卖票,所以希望我可以得到一个修复,这将允许这个特定的库卸载成功。 如果我不这样做,而且对于这个问题的一般情况,我很好奇这个选项是什么。
如果你只是从内存中卸载DLL后,你可以使用
UnmapViewOfFile
提供加载的dll的基地址作为参数。
HINSTANCE hInst = LoadLibrary( "path_to_dll" ); if( !FreeLibrary( hInst ) ) { fprintf( stderr, "Couldn't unload library. Error Code: %02X\n. Attempting to unmap...", GetLastError() ); if( !UnmapViewOfFile( hInst ) ) { fprintf( stderr, "Couldn't unmap the file! Error Code: %02X\n", GetLastError( ) ); } }
或者,如果它是一个没有显式加载的库(例如,一个库加载的库加载的库依赖项),而您没有该句柄,则使用GetmoduleeHandle :
HINSTANCE hInst = GetmoduleeHandle( "dllname_you_didn't_load" ); if( hInst != NULL ) { if( !UnmapViewOfFile( hInst ) ) { fprintf( stderr, "Couldn't unmap the file! Error Code: %02X\n", GetLastError( ) ); } }
我认为只有一个可能的解决方案 – 通过专用线程与DLL互操作。 所以及时你需要卸载你刚刚退出的DLL(或可能是杀死)该线程和所有与它关联的资源将被释放。 在这种情况下,你不能保证内存泄漏,但我建议这个解决方案暂时,直到三方修复DLL中的错误
这可能不是你遇到的问题,但在以下情况下:
当使用链接器支持运行时动态链接时,不要忘记使用/ Delay:Unload参数。