Disons que j'écris une DLL en C++, et déclare un objet global d'une classe avec un destructeur non trivial. Le destructeur sera-t-il appelé lorsque la DLL est déchargée?Qu'advient-il des variables globales déclarées dans une DLL?
Répondre
Dans une DLL Windows C++, tous les objets globaux (y compris les membres statiques de classes) seront construits juste avant l'appel de DllMain avec DLL_PROCESS_ATTACH et seront détruits juste après l'appel de DllMain avec DLL_PROCESS_DETACH.
Maintenant, vous devez tenir compte de trois problèmes:
0 - Bien sûr, les objets globaux non-const sont mauvais (mais vous savez déjà que, donc je vais éviter multithreading, serrures mentionnant, dieu-objets, etc. 1 - L'ordre de construction des objets ou des différentes unités de compilation (fichiers CPP) n'est pas garanti, donc vous ne pouvez pas espérer que l'objet A sera construit avant B si les deux objets sont instanciés dans deux CPP. Ceci est important si B dépend de A. La solution est de déplacer tous les objets globaux dans le même fichier CPP, car dans la même unité de compilation, l'ordre d'instanciation des objets sera l'ordre de construction (et l'inverse de la commande de destruction)
2 - Il y a des choses qu'il est interdit de faire dans le DllMain. Ces choses sont probablement interdites, aussi, dans les constructeurs. Évitez donc de bloquer quelque chose. Voir excellent blog de Raymond Chen sur le sujet:
http://blogs.msdn.com/oldnewthing/archive/2004/01/27/63401.aspx
http://blogs.msdn.com/oldnewthing/archive/2004/01/28/63880.aspx
Dans ce cas, l'initialisation paresseuse pourrait être intéressant: Les classes restent dans un état "non initialisé" (pointeurs internes sont NULL, les booléens sont faux, peu importe) jusqu'à ce que vous appeliez une de leurs méthodes, à quel point ils s'initialisent. Si vous utilisez ces objets à l'intérieur de la fonction principale (ou de l'une des fonctions descendantes du principal), cela ne pose aucun problème, car ils seront appelés après l'exécution de DllMain.
3 - Bien sûr, si certains objets globaux dans la DLL A dépendent d'objets globaux dans la DLL B, vous devez faire très attention à l'ordre de chargement des DLL, et donc aux dépendances.Dans ce cas, les DLL avec des dépendances circulaires directes ou indirectes vous causeront une quantité folle de maux de tête. La meilleure solution est de casser les dépendances circulaires. Notez qu'en C++, le constructeur peut lancer, et vous ne voulez pas d'exception au milieu d'un chargement de DLL, alors assurez-vous que vos objets globaux n'utiliseront pas d'exception sans une très bonne raison. Comme les destructeurs correctement écrits ne sont pas autorisés à lancer, le déchargement de la DLL devrait être correct dans ce cas.
Il doit être appelé lorsque l'application se termine ou que la DLL est déchargée, selon la première éventualité. Notez que cela dépend un peu du temps d'exécution réel que vous compilez.
Aussi, méfiez-vous des destructeurs non triviaux car il y a des problèmes de timing et de commande. Votre DLL peut être déchargé après une DLL sur laquelle votre destructeur s'appuie, ce qui causerait évidemment des problèmes.
Lorsque DllMain avec fdwReason = le paramètre DLL_PROCESS_DETACH est appelé, cela signifie que la DLL est déchargée par l'application. C'est le moment avant que le destructeur d'objets globaux/statiques soit appelé.
Cette page de Microsoft va dans les détails de l'initialisation de la DLL et la destruction de GLOBALS:
http://msdn.microsoft.com/en-us/library/988ye33t.aspx
Si vous voulez voir le code réel qui est exécuté lors de la liaison d'un .dll, jetez un oeil à %ProgramFiles%\Visual Studio 8\vc\crt\src\dllcrt0.c
.
À partir de l'inspection, les destructeurs seront appelés via _cexit()
lorsque le nombre de références internes maintenu par le CRT dll atteint zéro.
Dans les fichiers d'image binaires Windows avec l'extension * .exe, * .dll sont dans PE format Ces fichiers ont un point d'entrée. Vous pouvez le voir avec l'outil dumpbin comme
dumpbin/têtes dllname.dll
Si vous utilisez l'exécution C de Microsoft, votre point d'entrée sera quelque chose comme * ou * CRTStartup DllMainCRTStartup
De telles fonctions effectuent l'initialisation de l'exécution c et C++ et déléguent l'exécution à (main, WinMain) ou à DllMain respectivement.
Si vous utilisez le compilateur VC Microsofts alors vous pouvez regarder au code source de cette fonction dans le vôtre répertoire VC:
- crt0.c
- dllcrt0.c
processus DllMainCRTStartup toutes choses besoin d'init/deinit vos variables globales à partir de sections .data dans le scénario normal, quand il retrive notification DLL_PROCESS_DETACH au cours de la dll décharger. Par exemple:
- main ou WinMain de fil de démarrage du programme retourne le contrôle du flux
- vous appelez explictly FreeLibrary et utilisez-dll-compteur est zéro
- 1. PHP et des variables globales
- 2. Asp.net variables « globales »
- 3. Classes de refactoring utilisant des variables globales
- 4. Variables globales, Javascript
- 5. Variables d'environnement globales dans un script shell
- 6. Problème avec les variables globales
- 7. Comment/où libérer des variables globales dans l'objectif c? -iphone
- 8. l'accès à des variables globales dans un rappel
- 9. Puis-je utiliser __init__.py pour définir des variables globales?
- 10. Gestionnaires ASP.NET HTTP et variables globales
- 11. ASP.NET C# Les variables statiques sont globales?
- 12. Modifier les variables globales en C++
- 13. ne peut pas accéder à des variables globales dans une fonction usort?
- 14. Les variables déclarées localement ne peuvent pas être contrôlées
- 15. variables globales dans php ne fonctionne pas comme prévu
- 16. Comment sauvegarder les variables d'application globales dans WPF?
- 17. Quelle est la portée des variables déclarées dans un constructeur de classe?
- 18. Comment initialiser des variables globales dans TurboGears 2 avec des valeurs d'une table
- 19. variables threadlocales dans une servlet
- 20. Objectif C - Où gérez-vous les variables statiques globales?
- 21. Quelle est la meilleure façon de créer des variables globales dans CakePHP?
- 22. Comment refactoriser les variables globales à partir de votre code
- 23. Partage de variables globales sur plusieurs serveurs/applications
- 24. Problèmes avec les variables globales dans le projet de bibliothèque partagée (C++)
- 25. A propos de l'appel système fork et les variables globales
- 26. Parcourir le contenu des variables DLL de VC6 (DEBUG)
- 27. Partager des variables entre des fonctions en PHP sans utiliser de globales
- 28. Existe-t-il un moyen d'obtenir une liste de toutes les variables déclarées dans une méthode java?
- 29. gestion des erreurs javascript globales
- 30. Conserver les variables globales dans l'étendue de la bibliothèque dans C
Si un processus change une valeur globale, est le changement observé dans un autre processus? –
@ LB--: Habituellement, non: Chaque processus a sa propre variable globale * à moins que * vous ne les ayez mappés en mémoire partagée, ou utilisez un truc spécifique à l'OS pour les partager entre tous les processus utilisant cette DLL (je ne sais pas rappelez-vous exactement l'astuce sur Windows, mais cela impliquait des déclarations #pragma, IIRC) – paercebal