FreeLibrary API调用失败时该怎么办?

时间:2011-05-27 14:07:18

标签: c windows winapi dll native

问题

我有一个第三方DLL在尝试从我的本机C应用程序卸载时会抛出未处理的异常。这导致调用FreeLibrary失败,并且模块仍在我的进程中加载​​。

有没有强制卸载库的选项?

FreeLibrary调用时你会怎么做?

附加背景

当使用加载时动态链接时,这很烦人,但最终应用程序被操作系统拆除。使用运行时动态链接时会出现问题。我加载这个DLL,使用它,然后在某些情况下,我需要从我的进程的虚拟地址空间卸载它,然后继续运行。当我在第三方库上调用FreeLibrary时,它会执行一些清理工作(即调用DllMain when DLL_PROCESS_DETACH)。虽然它正在进行清理,但它会导致抛出一个它无法处理的异常,并且作为FreeLibrary的未处理异常冒泡。这会导致调用失败并且模块仍然加载。

我已经向供应商提供了一张票,所以希望我能得到一个修复程序,这将允许这个特定的库成功卸载。但是,如果我不这样做,并且对于这个问题的一般情况,我很好奇这些选项是什么。

3 个答案:

答案 0 :(得分:6)

如果你只是从内存中卸载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( ) );
   }
}

或者,如果它是您未显式加载的库(例如,由您加载的库加载的库依赖项)并且您没有句柄,则使用GetModuleHandle

HINSTANCE hInst = GetModuleHandle( "dllname_you_didn't_load" );
if( hInst != NULL )
{
   if( !UnmapViewOfFile( hInst ) )
   { 
     fprintf( stderr, "Couldn't unmap the file! Error Code: %02X\n", GetLastError( ) );
   }
}

答案 1 :(得分:1)

我认为只有一种可能的解决方案 - 通过专用线程与dll互操作。因此,您需要卸载DLL,只需退出(或可能是kill)该线程以及与其相关的所有资源都将被释放。在这种情况下,你不保证内存泄漏,但我建议这个解决方案是临时的,直到3d派对修复DLL中的错误

答案 2 :(得分:1)

这可能不是您遇到的问题,但如果是:

使用链接器支持进行运行时动态链接时,不要忘记使用/Delay:Unload参数。