ОБНОВЛЕНИЕ ДЛЯ .NET 4.0 И БОЛЕЕ НЕДАВНИХ Фреймворков
Это старый вопрос, который задавали во времена .Net 2.0, когда поддержка библиотек DLL смешанного режима имела серьезные проблемы с инициализацией, склонные к случайным тупикам. Начиная с .Net 4.0, инициализация библиотек DLL смешанного режима изменилась. Теперь есть два отдельных этапа инициализации:
- Собственная инициализация, вызываемая в точке входа библиотеки DLL, которая включает встроенную настройку времени выполнения C ++ и выполнение вашего метода DllMain.
- Управляемая инициализация, автоматически выполняемая загрузчиком системы.
Поскольку шаг №2 выполняется вне Loader Lock, взаимоблокировок нет. Подробности описаны в разделе «Инициализация смешанных сборок» .
Чтобы гарантировать, что ваша сборка в смешанном режиме может быть загружена из собственного исполняемого файла, единственное, что вам нужно проверить, - это то, что метод DllMain объявлен как собственный код. #pragma unmanaged
может помочь здесь:
#pragma unmanaged
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
... // your implementation here
}
Также важно, чтобы любой код, который DllMain может вызывать прямо или косвенно, также был неуправляемым. Имеет смысл ограничить тип функций, используемых DllMain, чтобы вы отслеживали весь код, доступный из DllMain, и обеспечивали его компиляцию с#pragma unmanaged
.
Компилятор немного помогает, предупреждая C4747, если он обнаруживает, что DllMain не объявлен как неуправляемый:
1> Generating Code...
1>E:\src\mixedmodedll\dllmain.cpp : warning C4747: Calling managed 'DllMain': Managed code may not be run under loader lock, including the DLL entrypoint and calls reached from the DLL entrypoint
Однако компилятор не будет генерировать никаких предупреждений, если DllMain косвенно вызывает какую-либо другую управляемую функцию, поэтому вам нужно убедиться, что этого никогда не произойдет, иначе ваше приложение может случайно заблокироваться.