8
votes

Suppression d'un objet créé dans une DLL

J'ai besoin de clarifier les problèmes d'exécution / de tas lors de la suppression d'un objet créé dans une DLL. Il a besoin d'une introduction avant de venir à mes questions ...

dans mon projet, une DLL (qui est spécifiée par son nom) renvoie un nouvel objet Grabber. Dans une version antérieure de mon code, la DLL a exporté une fonction comme celle-ci: p> xxx pré>

dans l'EXE J'ai utilisé une fonction statique comme celle-ci pour créer un nouvel objet Grabber: p> xxx pré>

dans l'EXE La durée de vie d'un objet Grabber est gérée par un pointeur intelligent: p> xxx pré>

Tout cela a fonctionné aussi longtemps. Comme je compilisai l'EXE et la DLL avec le paramètre / MDD MDD> (VC ++ 2010), ce qui signifie que EXE et DLL ont utilisé le même tas. P>

Maintenant, je veux compiler ma solution avec le paramètre / mtd code>. Avec cela, j'ai eu une analyse d'exécution de type _crtisvalidheappointer code> pour l'objet de chaîne de paramètres que j'ai transmis à la DLL. Cela a du sens car la DLL tente de supprimer un objet de chaîne créé dans l'EXE. Et ils n'utilisent plus le même tas. P>

J'ai eu autour de ce problème en modifiant la fonction DLL exportée un peu ( const char * code> au lieu de string ): p> xxx pré>

et dans CreatEgraBberObject code> i Pass grabbersettings.c_str () code> au lieu de Grabberssertings code> à la fonction DLL. P>

maintenant tout fonctionne bien. Mais maintenant vient ma première question forte>: pourquoi n'ai-je pas le _crtisvalidheappointer code> assertion lorsque mygrabberobj code> est supprimé? L'objet a été créé à partir de la DLL mais est supprimé de l'exe (par le pointeur intelligent). Pourquoi n'ai-je pas le même problème ici que avec l'objet String ci-dessus? P>

Je suppose qu'une solution propre serait que la DLL exporte également une fonction comme celle-ci: p> xxx

alors j'aurais aussi une fonction statique dans mon exe qui appelle DELETEGRABBER dans une DLL: p> xxx pré>

cette fonction statique pourrait alors automatiquement être appelle automatiquement par le SMART Pointeur: P>

shared_ptr<Grabber> myGrabberObj = shared_ptr<Grabber>(createGrabberObject("SomeGrabber.DLL", "Settings"), 
boost::bind(deleteGrabberObject, "SomeGrabber.DLL", _1));


0 commentaires

3 Réponses :


5
votes

La DLL est comptée de la DLL, non chargée deux fois, et lorsque vous utilisez LoadLibrary, il est seulement chargé une fois de toute façon et ils utiliseront le même tas. La fonction statique est la solution normale à ce problème.


1 commentaires

Merci! C'était vraiment vite!



3
votes

Pour votre deuxième question, juste parce que vous chargez que la DLL ne signifie pas deux cas. Le système d'exploitation est suffisamment intelligent pour le charger une fois.

Edit: Pour la première question, c'est probablement parce que le pointeur partagé ne dépasse jamais de portée ou parce que le temps d'exécution VC ne pouvait pas détecter le cas correctement (il n'a pas failli de faillite mais la mémoire n'était pas failli. libéré).


1 commentaires

Merci pour la réponse rapide! En réalité, le pointeur partagé est hors de portée (un point d'arrêt dans ~ somespecificGrabber dans la DLL est touché). Donc, on dirait que le temps d'exécution VC ne l'a pas détecté.



3
votes

Eh bien, c'est parce que (dans votre cas), deux tas fonctionnent. La DLL a un autre gestionnaire de démarrage et EXE est différent. Cela peut être dû à:

  • Contradiction de débogage / sortie
  • Le temps d'exécution VC utilisé (l'un est VC8, l'un est VC9 par exemple). Composé par dessus aussi!
  • Différents modèles utilisés pour construire dll / exe ( / mt [d] drapeau, reliant comme statique-lib etc).
  • Vous avez montré Supprimer contre Nouveau qui est valide. Mais cela peut également être cas où nouveau est en réalité malloc / heapalloc.

    En bref, la mémoire allouée par X HeP-Manager ne sera pas trouvée par Y Heap-Manager, et donc l'assertion!


0 commentaires