AKTUALIZACJA DLA .NET 4.0 I NOWOCZESNYCH RAM
Jest to stare pytanie zadawane w czasie .Net 2.0, kiedy obsługa bibliotek DLL trybu mieszanego miała poważne problemy z inicjalizacją, podatne na losowe zakleszczenia. Począwszy od .Net 4.0, zmieniła się inicjalizacja bibliotek DLL trybu mieszanego. Teraz są dwa oddzielne etapy inicjalizacji:
- Natywna inicjalizacja wywoływana w punkcie wejścia biblioteki DLL, która obejmuje natywną konfigurację środowiska wykonawczego C ++ i wykonanie metody DllMain.
- Zarządzana inicjalizacja, wykonywana automatycznie przez program ładujący system.
Ponieważ krok # 2 jest wykonywany poza blokadą modułu ładującego, nie ma zakleszczeń. Szczegóły opisano w sekcji Inicjalizacja zestawów mieszanych .
Aby upewnić się, że zestaw trybu mieszanego można załadować z natywnego pliku wykonywalnego, jedyną rzeczą, którą musisz sprawdzić, jest to, że metoda DllMain jest zadeklarowana jako kod natywny. #pragma unmanaged
może pomóc tutaj:
#pragma unmanaged
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
...
}
Ważne jest również, aby każdy kod, który DllMain może wywołać bezpośrednio lub pośrednio, był również niezarządzany. Sensowne jest ograniczenie typu funkcji używanej przez DllMain, aby śledzić cały kod osiągalny z DllMain i upewnić się, że jest on skompilowany #pragma unmanaged
.
Kompilator trochę pomaga, ostrzegając C4747, jeśli wykryje, że DllMain nie jest zadeklarowany jako niezarządzany:
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
Jednak kompilator nie wygeneruje żadnych ostrzeżeń, jeśli DllMain pośrednio wywoła inną funkcję zarządzaną, więc musisz upewnić się, że nigdy się to nie zdarzy, w przeciwnym razie aplikacja może się losowo zablokować.