ОНОВЛЕННЯ ДЛЯ .NET 4.0 І БІЛЬШЕ НОВИХ КАДРІВ
Це старе запитання, поставлене під час .Net 2.0, коли підтримка DLL в змішаному режимі мала серйозні проблеми з ініціалізацією, схильними до випадкових тупикових ситуацій. Станом на .Net 4.0 ініціалізація бібліотек DLL у змішаному режимі змінилася. Зараз є два окремі етапи ініціалізації:
- Власна ініціалізація, що викликається в точці входу DLL, що включає власне налаштування часу виконання C ++ та виконання вашого методу DllMain.
- Керована ініціалізація, що автоматично виконується завантажувачем системи.
Оскільки крок 2 виконується за межами блокування навантажувача, не існує тупикових ситуацій. Деталі описані в Ініціалізації змішаних зборів .
Щоб забезпечити завантаження змішаного режиму з власного виконуваного файлу, потрібно перевірити лише те, що метод 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 побічно викликає якусь іншу керовану функцію, тому вам потрібно переконатися, що цього ніколи не трапиться, інакше ваша програма може випадково заблокувати.