Question

J'ai récemment intégré le composant de journalisation .NET NLog dans l'une de nos applications développée uniquement en code non géré (composants C ++ et VB6 compilés dans Visual Studio 6). De nombreuses applications C ++ parlent à NLog via une interface COM.

Tout fonctionne correctement pour le moment, mais je remarque que le message suivant apparaît (dans la fenêtre de sortie si vous déboguez le composant C ++ dans VS6; une invite dans l'EDI si vous déboguez NLog via VS 2005) lors de l'arrêt du programme:

  

LoaderLock a été détecté Message:   Tentative d'exécution gérée dans le système d'exploitation   Verrou de chargeur. Ne pas essayer de courir   code managé dans un DllMain ou une image   fonction d'initialisation depuis le faire   peut provoquer le blocage de l'application.

Le DllMain est comme suit:

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _Module.Init(ObjectMap, hInstance);
        DisableThreadLibraryCalls(hInstance);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
        _Module.Term();
    return TRUE;    // ok
}

Je suppose que _Module.Term(); inclut désormais la publication de certaines références .NET (je garde une référence à un objet NLog dans l'une de mes classes C ++ pour éviter d'avoir à instancier et à publier à chaque fois) ce qui provoque cet avertissement. pour apparaître.

Ma question: est-ce sûr d'ignorer? Si ce n'est pas le cas, qu'est-ce qu'une bonne solution de contournement? (Le mieux que je puisse penser est d'instancier une référence à cet objet NLog et de le publier chaque fois que je veux écrire dans le fichier journal ... ce n'est pas la solution la plus élégante.)

Était-ce utile?

La solution

Il est définitivement déconseillé d’ignorer ce message. Si vous cliquez sur ce message, vous avez presque certainement créé une véritable violation de la politique de verrouillage du chargeur. Il s'agit d'une erreur très grave pouvant entraîner un comportement imprévisible dans un programme (y compris une impasse).

Le meilleur moyen d'éviter cela est de ne pas accéder à d'autres objets / fonctions .Net directement ou indirectement dans la DLL principale. Dans votre cas, il est probablement préférable d'utiliser une stratégie de cache différente. Peut-être créer un objet compté ref pour contenir la référence .Net. De cette façon, l'objet sera libéré avant que DllMain soit appelé pour déchargement (la DLL ne peut pas être déchargée tant que tous vos objets ne sont pas détruits).

Autres conseils

Ne pas ignorer. J'ai eu un problème LoaderLock au démarrage d'une application C # qui utilisait une DLL C ++ non gérée. Dans ce cas, une partie du code de la DLL (porté depuis Linux) avait des statiques qui accédaient aux fichiers lors de l’initialisation lors du chargement. Une fois les statiques nettoyées, le problème LoaderLock a été résolu. De la même manière, si vous avez des statistiques C / C ++ qui accèdent aux fichiers pendant le nettoyage, cela pourrait contribuer à votre LoaderLock.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top