2010-07-06 4 views
1

J'utilise une bibliothèque (ANet) qui est écrite nativement en C et j'interface avec lui en utilisant C# via un petit sous-ensemble dll wrapper que j'ai fait en C et lié statiquement à celui-ci. La bibliothèque (ANet) a un DllMain qui suit simplement le nombre de références à celle-ci (donc "Process attach" et "Thread attach" compte) mais il semble aller dans le négatif (c'est-à-dire plus de détachements que d'attaches).Les appels DllMain à partir de la création/suppression de thread C# semblent être déséquilibrés?

Voici la DllMain de ANet. Il est assez simple:

BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) 
{ 
    static int procRefCount = 0; 
    static int threadRefCount = 0; 

    switch (fdwReason) { 
    case DLL_PROCESS_ATTACH: 
     procRefCount++; 
     break; 

    case DLL_PROCESS_DETACH: 
     procRefCount--; 
     break; 

    case DLL_THREAD_ATTACH: 
     threadRefCount++; 
     break; 

    case DLL_THREAD_DETACH: 
     threadRefCount--; 
     break; 

    } 

    if (procRefCount < 0) { 
     MessageBox(NULL, "Bug - negative processes?", "DP DLL Error", MB_OK|MB_ICONERROR); 
     return FALSE; 
    } 
    if (procRefCount > 1) { 
     MessageBox(NULL, "Bug - too many processes trying to use DP", "DP DLL Error", MB_OK|MB_ICONERROR); 
     return FALSE; 
    } 
    if (threadRefCount < 0) { 
     MessageBox(NULL, "Bug - negative threads?", "DP DLL Error", MB_OK|MB_ICONERROR); 
     return FALSE; 
    } 
    /* Only the first thread is allowed to join? */ 
    if (threadRefCount > 0) { 
     //MessageBox(NULL, "Bug - too many threads trying to use DP", "DP DLL Error", MB_OK|MB_ICONERROR); 
     return FALSE; 
    } 

    return(TRUE); 
} 

.. Ce qui je vise à changer pas si je n'ai pas recompiler et redistribuer cette bibliothèque préconstruite.
Comme C# semble créer et détruire aléatoirement des threads, DllMain est appelé de façon sporadique tout au long de mon programme. La chose est que la boîte de message disant "Bug - threads négatifs?" affichera souvent aussi!

Pourquoi y aurait-il plus de messages THREAD_DETACH que de messages THREAD_ATTACH?

Répondre

3

Plus de threads sont sortis pendant la durée de vie de la DLL que créés pendant la durée de vie de la DLL. Les threads ne se souviennent pas des DLL présentes lors de leur création. Vous obtenez donc un message de détachement pour chaque thread qui se ferme après le chargement de la DLL, mais vous ne recevez que les messages attachés aux threads créés après la création de la DLL. chargé. Donc, si vous créez des threads n, chargez une DLL, puis fermez ces threads, la DLL voit les messages nDLL_THREAD_DETACH mais pas les messages DLL_THREAD_ATTACH.

Il appartient à la DLL de décider de faire ou non quelque chose avec le thread détaché et de se souvenir s'il l'a déjà vu ou non; le 'si' est important dans 'Si la DLL a stocké un pointeur sur la mémoire allouée dans un emplacement TLS, elle doit utiliser cette opportunité pour libérer la mémoire.' MSDN

+0

+1, très plausible. –

+0

Bon point, les threads peuvent avoir été créés avant que la DLL ait été chargée (même si elle est en charge de programme) qui seront supprimés plus tard. Cela signifie que c'est un fonctionnement normal, ce qui est bien, mais c'est encore un problème difficile à résoudre pour moi – user382954

+0

@zeiphon Je ne sais pas si la librairie vous permet de l'utiliser dans un environnement multi-threads (le point d'interrogation dans le commentaire dans la source implique que les auteurs ne savaient pas non plus). Vous pouvez peut-être le pirater en appelant vous-même DllMain (0, DLL_THREAD_ATTACH, 0) plusieurs milliers de fois pour incrémenter le compteur de threads, mais vous devez également vous assurer que tous les appels dans la DLL proviennent du même thread, ce qui est plus compliqué si vous utilisez une interface graphique .net. –

Questions connexes