Question

J'ai 2 objets statiques dans 2 différents dll :

Un objet Ressources (ce qui est un singleton), et un objet utilisateur . L'utilisateur de l'objet dans son destructor doit accéder à des ressources d'objet.

Comment puis-je forcer des ressources d'objet ne doit pas être détruites avant objet utilisateur?

Était-ce utile?

La solution

Les objets globaux sont détruits lorsque leur est déchargé DLL correspondant. Alors que votre « utilisateur » dll est probablement dépendante de votre dll « ressources », vous êtes en difficulté: « ressource » sera toujours détruit avant « utilisateur »

.

Je suis aussi intéressé par une bonne réponse à cette question, si l'on existe. Jusqu'à présent, j'utilise une fonction de nettoyage qui doit être appelé par l'application avant qu'elle ne quitte, et je ne garder que le code inoffensif Destructeurs.

Autres conseils

Si vous êtes en mesure de mettre que 2 variables globales dans la même DLL ce n'est pas la même histoire. Comme dit par Jem dans sa propre réponse, DLL ordre detachement n'est pas garanti par le système. Par conséquent, vous pouvez avoir un gros problème quand ayant 2 séparés Dlls. Je ne suis pas un gourou du système Windows, mais d'avoir un regard avec Google, j'ai trouvé blogueurs msdn qui dit qu'ils avaient le même problème avec pas de bonne solution pour y remédier.

Je vous êtes en mesure de les mettre dans un même DLL, selon moi, la solution est plus facile, dans ce cas, vous n'avez pas besoin d'aborder la question « non GARANTI de commande DLL detachement » (sans solution pour autant que je comprends) .
Mais alors vous avez encore besoin de répondre à une nouvelle question: ordre de destruction variable globale n'est pas garantie par le langage C ++. Mais celui-ci peut être adressé:

vous devez utiliser une sorte de couting de référence. un coup de pouce :: shared_ptr peut faire l'affaire.

déclarer global et définir ainsi:

boost::shared_ptr my_resource_ptr ( new Resource() ); // new operator is important here!

Ensuite, vous devez modifier votre implémentation utilisateur magasin sa propre shared_ptr:

class User
{
    ...
    boost::share_ptr a_resource_ptr;
    ...
};

Tant que tout l'un de l'instance de l'utilisateur n'est pas détruite, ceux-ci « conserver » l'instance de ressources, et ainsi l'empêcher d'être prematuraly supprimé, même si la shared_ptr mondiale aurait pu être détruite.
La dernière instance de l'utilisateur détruite sera (undirectly) supprimer l'instance des ressources.

Quelle que soit la référence que vous utilisez le comptage, ComPtr, vous-même, il devrait faire l'affaire.

Je ne pense pas que vous pouvez changer l'ordre de destruction de globals qui sont dans des modules différents. Toute chance d'ajouter une référence de comptage?

Dans le cas où vous voulez vraiment obtenir 2 séparés Dlls je peux avoir quelques conseils pour vous: vous pouvez envisager l'utilisation de l'API de FreeLibrary() de Windows. Comme indiqué par msdn Décrémentation LoadLibrary() compteur de référence pour la DLL qui est déchargé lorsque le compteur atteint 0.

Inconvénient: en utilisant implique que vous GetProcAddress() il chargement avec main() ( lien msdn ) et d'appeler la fonction de cette bibliothèque implique que vous utilisez la fonction DllMain(), ce qui peut conduire à un code vraiment laid. Et cela peut impliquer un changement dans votre code aussi - que d'obtenir poiting variable globale aux fonctions de la dll afin de stocker l'adresse de chaque fonction ...

Si vous voulez la mettre en œuvre:

  1. vous devez charger et libérer la bibliothèque de votre fonction de votre DLL_PROCESS_DETACH processus,
  2. et aussi charger et libérer la bibliothèque de la dll implenting la classe utilisateur. Mettre en œuvre dans la fonction de cette dll <=>, quand la raison est <=> (voir lien DllMain de MDSN .

Ainsi, il déchargera que la bibliothèque « ressources » une fois la bibliothèque « Utilisateur » ont fini avec elle.

Ayez un essai si vous et permettez-moi de dire si cela fonctionne comme je n'implémenté ..

Ps: J'ai posta deuxième réponse à votre question pour obtenir une séparation significative entre les deux réponses que je (essayer de) détail les deux. Je ne veux pas que vous les mélanger et obtenir confus ...

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