Что делать при сбое вызова API FreeLibrary?

вопрос

у меня есть сторонняя DLL, которая выдает необработанное исключение при попытке выгрузить его из родной приложения. Это приводит к вызову FreeLibrary сбой, и модуль остается загруженным в моем процессе.

есть ли варианты forceably выгрузить библиотеку?

что вы делаете, когда функцию freelibrary звонки?

Дополнительную Информацию

когда использование динамического связывания во время загрузки это достаточно раздражает, но в конечном итоге приложение сносится ОС. Проблема возникает при использовании динамической компоновки во время выполнения. Я загружаю эту DLL, использую ее, а затем в некоторых случаях мне нужно выгрузить ее из виртуального адресного пространства моего процесса, а затем продолжить работу. Когда я вызываю FreeLibrary в сторонней библиотеке, он выполняет некоторую очистку (т. е. в DllMain когда DLL_PROCESS_DETACH называется). Хотя это разгребать это вызывает исключение, которое он не обрабатывает, и пузырится как необработанное исключение для FreeLibrary. Это приводит к сбою вызова, а модуль остается загруженным.

Я поставил билет с поставщиком, поэтому, надеюсь, я смогу получить исправление, которое позволит этой конкретной библиотеке успешно выгрузить. В случае, если я этого не делаю, и для общего случая этой проблемы мне любопытно, каковы варианты.

3 ответов


Если вы только после выгрузки 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( ) );
   }
}

Я думаю, что есть только одно возможное решение - взаимодействие с dll через выделенный поток. Поэтому со временем вам нужно выгрузить dll, вы просто выходите (или можете убить), что поток и все связанные с ним ресурсы будут освобождены. В этом случае вам не гарантируется утечка памяти, но я предлагаю это решение как временное, пока 3d party не исправит ошибки в dll


Это, вероятно, не проблема, которую вы испытываете, но в случае, если это:

при использовании поддержки компоновщика для динамической компоновки во время выполнения не забудьте использовать /Задержка:Разгрузить