Точка входа DllMain
предназначена для выполнения только простых задач инициализации или завершения. По техническим причинам то, что вам разрешено делать в DllMain
, очень ограничено. См. эту ссылку для получения дополнительной информации.
Инициируя загрузку файла, вы, вероятно, вызываете загрузку новых DLL, что не следует делать в DllMain
, так как это может вызвать тупик.
Если вы хотите, чтобы ваша DLL имела функцию инициализации без этих ограничений, то вам не следует использовать функцию точки входа DllMain
(за исключением простой инициализации). Скорее, вам следует подождать, пока операционная система полностью завершит загрузку вашей DLL.
Например, вам может потребоваться, чтобы все программы, использующие вашу DLL, вызывали специальную функцию инициализации внутри вашей DLL, прежде чем вызывать какие-либо другие функции. внутри вашей DLL. Это довольно часто для DLL, чтобы требовать этого. Например, библиотека DLL библиотеки Microsoft Windows Sockets 2 (Ws2_32.dll) требует, чтобы вы вызывали WSAStartup
перед вызовом любых других ее других функций. Эта специальная функция инициализации не имеет тех же ограничений, что и DllMain
, потому что технически это обычный вызов функции. Следовательно, он позволяет вам выполнять такие вещи, как загрузка файлов.
В качестве альтернативы ваша DLL может отслеживать, инициализировалась ли она в глобальной переменной. В DllMain
вы ничего не делаете, кроме как задаете для этой глобальной переменной значение 0 (false). Всякий раз, когда вызывается экспортированная функция в вашей DLL, ваша функция DLL может проверить эту глобальную переменную, и если ваша DLL еще не инициализировала себя, она вызовет специальную функцию инициализации вашей DLL, которая выполняет загрузку и устанавливает для глобальной переменной значение 1 ( true).
Однако проверка глобальной переменной при каждом вызове функции может быть дорогой с точки зрения производительности. Поэтому первый метод может быть предпочтительнее второго.