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> dans l'EXE J'ai utilisé une fonction statique comme celle-ci pour créer un nouvel objet Grabber: p> dans l'EXE La durée de vie d'un objet Grabber est gérée par un pointeur intelligent: p> Tout cela a fonctionné aussi longtemps. Comme je compilisai l'EXE et la DLL avec le paramètre Maintenant, je veux compiler ma solution avec le paramètre J'ai eu autour de ce problème en modifiant la fonction DLL exportée un peu ( et dans maintenant tout fonctionne bien. Mais maintenant vient ma Je suppose qu'une solution propre serait que la DLL exporte également une fonction comme celle-ci: p> alors j'aurais aussi une fonction statique dans mon exe qui appelle DELETEGRABBER dans une DLL: p> cette fonction statique pourrait alors automatiquement être appelle automatiquement par le SMART Pointeur: P> / MDD MDD> (VC ++ 2010), ce qui signifie que EXE et DLL ont utilisé le même tas. P> / 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> const char * code> au lieu de string ): p> CreatEgraBberObject code> i Pass grabbersettings.c_str () code> au lieu de Grabberssertings code> à la fonction DLL. P> _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> shared_ptr<Grabber> myGrabberObj = shared_ptr<Grabber>(createGrabberObject("SomeGrabber.DLL", "Settings"),
boost::bind(deleteGrabberObject, "SomeGrabber.DLL", _1));
3 Réponses :
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. P>
Merci! C'était vraiment vite!
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. P>
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é). p>
Merci pour la réponse rapide! En réalité, le pointeur partagé est hors de portée (un point d'arrêt dans ~ somespecificGrabber code> dans la DLL est touché). Donc, on dirait que le temps d'exécution VC ne l'a pas détecté.
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û à: p>
/ mt [d] code> drapeau, reliant comme statique-lib etc). li>
- Vous avez montré
Supprimer code> contre Nouveau code> qui est valide. Mais cela peut également être cas où nouveau code> est en réalité malloc / heapalloc. Li>
ul>
En bref, la mémoire allouée par X STRY> HeP-Manager ne sera pas trouvée par Y Strort> Heap-Manager, et donc l'assertion! p>