Почему бы не вызвать FreeLibrary из функции точки входа? - PullRequest
4 голосов
/ 14 декабря 2009

Я пишу DLL, которая должна динамически вызывать отдельную DLL несколько раз. Я хотел бы сохранить вызываемого абонента, а затем просто выгрузить его, когда моя DLL выгружается. Но, по словам Microsoft, это плохая идея .

Функция точки входа должна только выполнять простые задачи инициализации и не должен вызывать любую другую DLL функции загрузки или завершения. За Например, в функции точки входа, Вы не должны прямо или косвенно вызвать функцию LoadLibrary или Функция LoadLibraryEx. Дополнительно, Вы не должны вызывать FreeLibrary функционировать, когда процесс терминатор.

Вот код ошибки. Может кто-нибудь объяснить, почему я не должен вызывать LoadLibrary и FreeLibrary из точки входа моей DLL?

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
switch (ul_reason_for_call) {
    case DLL_PROCESS_DETACH :
            if (hLogLib != NULL) FreeLibrary(hLogLib);
            break;
    }
    return TRUE;
}

Ответы [ 3 ]

4 голосов
/ 15 декабря 2009

Я думаю, что нашел ответ .

Функция точки входа должна выполнить только простую инициализацию или Завершение задач. Не должен звонить LoadLibrary или LoadLibraryEx функция (или функция, которая вызывает эти функции), потому что это может создать петли зависимостей в DLL порядок загрузки. Это может привести к DLL используется до того, как система выполнил свой код инициализации. Аналогично, функция точки входа не должен вызывать функцию FreeLibrary (или функция, которая вызывает FreeLibrary) во время завершения процесса, потому что это может привести к использованию DLL после того, как система выполнила код завершения.

2 голосов
/ 15 декабря 2009

Не делайте ничего важного внутри DLLMain. Шутки в сторону. Вызов FreeLibrary еще хуже, потому что он будет только в иногда взаимоблокировке, если случится так, что ваше свободное значение уменьшит refcount до нуля и библиотека фактически освободится.

2 голосов
/ 14 декабря 2009

Вы не можете вызвать LoadLibrary из своей точки входа, потому что функция DllMain выполняется внутри блокировки загрузчика ОС, и любые попытки повторно получить эту блокировку загрузчика (например, путем вызова LoadLibrary) приведут к взаимоблокировке.

...