AGGIORNAMENTO PER .NET 4.0 E ULTERIORI FRAMEWORK
Questa è una vecchia domanda posta al momento di .Net 2.0, quando il supporto per le DLL in modalità mista presentava seri problemi di inizializzazione, soggetti a deadlock casuali. A partire da .Net 4.0, l'inizializzazione delle DLL in modalità mista è cambiata. Ora ci sono due fasi separate di inizializzazione:
- Inizializzazione nativa, chiamata al punto di ingresso della DLL, che include l'installazione runtime C ++ nativa e l'esecuzione del metodo DllMain.
- Inizializzazione gestita, eseguita automaticamente dal caricatore di sistema.
Poiché il passaggio n. 2 viene eseguito al di fuori del blocco del caricatore, non sono presenti deadlock. I dettagli sono descritti in Inizializzazione di assembly misti .
Per garantire che l'assembly in modalità mista possa essere caricato da un eseguibile nativo, l'unica cosa che devi controllare è che il metodo DllMain sia dichiarato come codice nativo. #pragma unmanaged
potrebbe aiutare qui:
#pragma unmanaged
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
... // your implementation here
}
È inoltre importante che qualsiasi codice che DllMain potrebbe chiamare direttamente o indirettamente non sia gestito. Ha senso limitare il tipo di funzionalità utilizzato da DllMain in modo da tenere traccia di tutto il codice raggiungibile da DllMain e assicurarsi che sia tutto compilato #pragma unmanaged
.
Il compilatore aiuta un po 'dandoti un avvertimento C4747 se rileva che DllMain non è dichiarato come non gestito:
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
Tuttavia, il compilatore non genererà alcun avviso se DllMain chiama indirettamente qualche altra funzione gestita, quindi è necessario assicurarsi che non accada, altrimenti l'applicazione potrebbe bloccarsi in modo casuale.