ATUALIZAÇÃO PARA .NET 4.0 E MAIS FRAMEWORKS RECENTES
Essa é uma pergunta antiga feita na época do .Net 2.0, quando o suporte para DLLs de modo misto apresentava sérios problemas de inicialização, sujeitos a deadlocks aleatórios. A partir do .Net 4.0, a inicialização de DLLs de modo misto foi alterada. Agora, existem dois estágios separados de inicialização:
- Inicialização nativa, chamada no ponto de entrada da DLL, que inclui configuração nativa em tempo de execução C ++ e execução de seu método DllMain.
- Inicialização gerenciada, executada automaticamente pelo carregador do sistema.
Como a etapa 2 é executada fora do Loader Lock, não há deadlocks. Os detalhes são descritos em Inicialização de montagens mistas .
Para garantir que seu assembly de modo misto possa ser carregado de um executável nativo, a única coisa que você precisa verificar é se o método DllMain é declarado como código nativo. #pragma unmanaged
poderia ajudar aqui:
#pragma unmanaged
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
... // your implementation here
}
Também é importante que qualquer código que DllMain possa chamar direta ou indiretamente também não seja gerenciado. Faz sentido limitar o tipo de funcionalidade usada pelo DllMain para que você rastreie todo o código acessível a partir do DllMain e garanta que foi compilado com ele #pragma unmanaged
.
O compilador ajuda um pouco, avisando C4747 se detectar que DllMain não foi declarado como não gerenciado:
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
No entanto, o compilador não gerará nenhum aviso se DllMain chamar indiretamente alguma outra função gerenciada, portanto, você precisa garantir que isso nunca aconteça, caso contrário, seu aplicativo pode travar aleatoriamente.