Pour une raison quelconque, le retour d'une chaîne d'une fonction DLL bloque mon programme lors de l'exécution avec l'erreur d'erreur J'ai vérifié que ce n'est pas un problème avec la fonction elle-même en compilant le code DLL en tant que fonctions avec d'autres types de retour ( code source pour DLL: p> . p> code source pour le testeur: p> éditer: J'utilise VS2010. P> Une solution de contournement est de vous assurer que la bibliothèque et la source sont compilé à l'aide du même compilateur Non gérée à 0x775DFBAE dans la bibliothèque de Cranberry Tester.exe: Microsoft C ++ Exception: STD :: OUT_OF_RANGE à la mémoire 0x001EF604 .. code>.
.exe code> et en faisant quelques tests simples dans le
principal > fonction. p>
int code>,
double code>, etc.) fonctionne parfaitement. p>
Conclusion h1>
7 Réponses :
Cela se produit car vous allouiez la mémoire dans une DLL (à l'aide de constructeur de STD :: String) et de la libérer dans une autre DLL. Vous ne pouvez pas faire cela parce que chaque DLL installe généralement son propre tas. P>
Cela signifie-t-il que je dois utiliser des types 100% - "normaux" (c'est-à-dire char * code>)? Y a-t-il vraiment un moyen de faire cela?
@maxpm: Si tel est le cas, vous pourrez peut-être passer une chaîne STD :: String en tant qu'argument de sortie; e.g.: void getGreeting (string & s) {s.Asign ("Hello World!"); } code> Ceci peut ou non fonctionner, en fonction de la piste des allocateurs entre le code DLL et non-DLL. Vous voudriez essayer de mettre une chaîne beaucoup plus grande dans, juste pour être sûr.
Juste une pensée, utiliserait un allocateur personnalisé sur les cordes STD :: Les cordes qui vivent complètement d'un côté de l'aide de la limite DLL? Qui pourrait éventuellement s'assurer que l'allocation et la libération de la mémoire se produisent tous du même tas
@BDK: Cela devrait fonctionner - bien sûr, ce ne serait pas un std :: string code> tout cependant. (Ce serait un
std :: basic_string
Un peu en retard, mais la peine d'ajouter à la réponse de Billy: un allocator personnalisé peut capturer les fonctions d'allocation Opérateur Nouveau code> et
de l'opérateur Supprimer code> de l'unité de traduction actuelle, donc "Relialisation" allocator à la DLL d'origine. Voir mon
modulebound_allocator code>
que j'ai utilisé avec succès depuis des années . Au lieu de std :: string code> /
std :: wstring code> i utilisé
typedf std :: basique_string
@Klaus: Cela ne fonctionnera pas pour le cas de l'OP - le même compilateur / version doit être utilisé.
@Billy hmm, la même chose s'applique à votre réponse en raison d'objets définis par l'utilisateur C ++ en général ... mais le modulebound_allocator code> peut être utilisé lors de la liaison à l'exécution statique, donc je ne vois donc pas le problème En ce qui concerne ma réponse?
@Klaus: sur différentes versions de compilateur, les entrailles de std :: string code> ne correspondent pas. Essayer de regarder, par exemple, de Visual C ++ 2012's
std :: string code> dans GCC, ou même dans une autre version de Visual C ++, ne fonctionnerait pas, car la mise en page des données est différente. Votre solution proposée résout le cas où quelqu'un a suivi la voie vraiment mauvaise de lier de manière statique du CRT dans une DLL. Mais si les versions du compilateur ne correspondaient pas, les mauvaises choses vont toujours arriver.
@Billy a accepté, n'a jamais dit quelque chose de différent. Je ne vois tout simplement pas le raisonnement sur la ciblage de mon commentaire, qui ajoute simplement à votre MyallocaTortype Code>
@Klaus: seule raison est que son récent :) Les autres commentaires ont été affichés avant que l'OP précise qu'il utilisait différentes versions de compilateurs / compilateur.
Étant donné que votre message d'erreur indique que vous utilisez Microsoft C ++, je proposerai une réponse spécifique MS. P>
Tant que vous compilez à la fois l'EXE et la DLL avec le même compilateur, et liez les deux la même version de l'exécution de manière dynamique, alors tout ira bien. Par exemple, en utilisant "DLL multi-thread" pour les deux. P>
Si vous associez un lien entre le temps d'exécution statique, ou un lien contre différentes versions du temps d'exécution, alors vous êtes sol pour les raisons @Billy Oneal Soin Out (la mémoire sera attribuée dans un tas et libéré dans un autre). P>
Je ne comprends pas pourquoi le tas serait utilisé du tout? Il est passé de valeur et doit être renvoyé par la valeur sur la pile.
La chaîne est transmise par la valeur sur la pile. Un nouvel objet de chaîne doit donc être créé sur la pile en appelant son constructeur de copie. Ce constructeur peut utiliser le stockage de tas pour le texte réel, s'il est stocké que sur la pile, redimensionner la chaîne plus tard serait problématique
@BDK: Cela clarifie. Étrange cela fonctionne pour une LIB statique dans VS2008.
Pour clarifier, la bibliothèque doit être compilée sous la forme d'un DLL B> avec les mêmes paramètres B>? Ne fonctionnera-t-il pas si c'est compilé comme une bibliothèque statique? Si cela fonctionne, les réglages doivent-ils toujours être les mêmes?
J'ai compilé votre échantillon dans VS2008 et VS2010 et j'ai pu compiler et exécuter avec succès avec succès et exécuter sans problème. J'ai compilé la bibliothèque à la fois comme une bibliothèque statique et dynamique. P>
Ce qui suit concerne ma discussion avec BDK et imaginaire. Je ne l'ai pas supprimé car il pourrait être d'un certain intérêt pour quelqu'un. Strong> p> OK Cette question me dérange vraiment parce qu'elle ressemble à sa valeur non rémunérée. Il n'apparaît que des objets créés dans le tas, il semble être entièrement basé sur la pile. P> J'ai fait un test rapide pour vérifier comment les objets sont passés dans des studios visuels (compilés en mode de sortie sans Link Time Optimisation et optimisation désactivés). em> p> Le code: h2>
le démontage: h2>
la pile: h2>
pourquoi il s'applique: h2>
getGreetips () code>. Je ne vois pas de tas de tas créés. Je ne vois pas le tas d'avoir quelque chose à voir avec le problème. P>
J'ai eu un tel problème qui a été résolu par: p>
Utilisation de la bibliothèque d'exécution en tant que DLL à la fois pour l'application et la DLL (afin que l'attribution soit manipulée dans un lieu unique) P> li>
Assurez-vous que tous les paramètres du projet (compilateur, lieur) sont les mêmes sur le projet P> LI> ul>
Tout comme Snmacdonald, j'ai été incapable de reproduire votre crash, dans des circonstances normales. D'autres déjà mentionnés:
Propriétés de configuration -> Génération de code -> Library d'exécution EM> doit être exactement fort> le même p>
Si je change l'un d'entre eux, je reçois votre crash. J'ai à la fois la DLL et EXE définis à la DLL multi-thread. P>
Vous pouvez renvoyer un La fonction inline est compilée avec le programme utilisant la DLL, pas lorsque la DLL est compilée. Cela évite les problèmes rencontrés par des roulements incompatibles ou des commutateurs compilateurs incompatibles. P> En fait, vous ne devez revenir que des types standard de votre DLL (telles que Passer dans un paramètre std :: chaîne code> d'une classe aussi longtemps que vous en ligne la fonction crée la chaîne. Ceci est fait, par exemple, par la boîte à outils QT dans leur
qstring :: tostdstring code> méthode:
const char * code> et
int code> ci-dessus) et ajoutez des fonctions inline pour les convertir en
std :: string () code>. P>
String & code> peut également être dangereux car ils sont souvent mis en œuvre sous forme de copie sur l'écriture. p> p>
Tout comme User295190 et Adam a déclaré que cela fonctionnerait bien si les mêmes paramètres de compilation sont corrects. p>
Par exemple, dans QT Qstring :: TOSTDSTRING () Retournerait une chaîne STD :: String et vous pouvez l'utiliser dans votre EXE de qtcore.dll. P>
Il se bloque si DLL et EXE avaient des paramètres de compilation différents et de relier les paramètres. Par exemple, DLL liée à MD et EXE liés à la bibliothèque MT CRT. P>
Y a-t-il du code que vous pouvez nous montrer? Ou le code n'est-il pas le vôtre?
@Birr mise à jour avec le code exemple.
@Maxpm: Cela compile pour moi dans Visual Studios 2008. Quel compilateur utilisez-vous?
@snmcdonald Il compile aussi pour moi. Essayer de l'exécuter quand tout est lié-up dans l'erreur.
@Maxpm: il compile et fonctionne dans vs2008
@Maxpm: Quelle version de VS utilisez-vous?
@snmc vs2010. Désolé pour l'ambiguïté.
Si je comprends bien, si la DLL et les EXE sont compilés avec le même compilateur (à boutez-vous et les mêmes niveaux de correctifs) et exactement les mêmes versions de bibliothèques et les mêmes options de compilateur, sa possible pour la DLL et EXE de partager un tas ainsi Cela peut fonctionner, toute autre combinaison peut vous donner des problèmes comme vous vivez
@Maxpm: BDK a un excellent point sur CRTS Check Out: msdn.microsoft.com/en-us/library/ms235460 (v = vs.80) .aspx Bien que cela ne soit pas un problème si vous construisez les deux projets avec la même version de VS2010 avec le même CRT.
@SNMC @BDK Bon points. Étrangement, cependant, cela est I> étant compilé avec la même version.
@Maxpm: compile et exécute avec succès pour la bibliothèque statique ou dynamique VS2008 et VS2010.