2010-02-25 51 views
0

J'ai une application Qt qui utilise une autre bibliothèque dans laquelle la sortie de la fonction est std :: string au lieu d'une chaîne QString.L'utilisation de std :: string avec Qt provoque une erreur d'exécution lors de la destruction

Donc, dans mon programme, j'ai une méthode

void doSomething() { 
... 
std::string std_string = MyExternalLibraryThatReturnsSTLstring.getString(); 
QString myQString = QString::fromStdString(std_string); 
... 
process(myQString); 
... 
} 

Quand mon lib externe retourne un std :: non vide tout chaîne fonctionne très bien. Mais lorsqu'une chaîne std :: string vide est renvoyée, l'application se bloque à la fin de la portée. Je suppose que cela a à voir avec la destruction de l'objet std :: string (?).

La conversion vers QString fonctionne correctement, même avec une chaîne std :: string vide.

Quelqu'un peut-il me dire pourquoi cela se produit, et comment éviter cette erreur d'exécution?

(Dans d'autres discussions certaines personnes ont discuté mélange de débogage et de libérer les bibliothèques, mais je ne pense pas que je l'ai fait. Comment savoir btw?)

Répondre

0

utilisation « marcheur de dépendance » pour voir où DLL votre application (et la DLL externe et la DLL QT) s'appuient.

+0

ok .. Je l'ai fait et il utilise seulement le standard Qt libs + mon external.dll qui utilise encore beaucoup de choses. Je ne peux pas vraiment dire s'il y a quelque chose qui ne va pas ou pas ici, mais ça ne semble pas être le cas. – Magus

1

La solution est de vous assurer que votre version Qt est compilée avec le même compilateur que vous utilisez pour votre application.

Dans mon cas, j'ai téléchargé Qt 4.7.3 qui a été pré-construit avec VS2008. Lorsque je suis passé à VS2010, toStdString provoquait le blocage de mon application. J'aurais aussi d'autres erreurs étranges avec les chaînes STL. Donc, configurez simplement votre version, et refaites-la avec le compilateur VS2010.

0

Ce que vous devez regarder en utilisant le Dependency Walker (qui Patrick suggère) pour est différentes versions des libs d'exécution msvc (msvcrt et amis), et si elles sont utilisées par différentes dll qui arrivent à échanger mémoire entre leur.

Ceci est la partie cruciale, puisque le tas est conservé dans la DLL d'exécution, chaque exécution aura son propre tas (c'est-à-dire pour vs 2008, 2010, 2005). Donc, si vous allouez de la mémoire dans une DLL (disons en créant une chaîne std :: string avec plus de 16 caractères) et l'envoyez à une autre DLL où elle meurt (à la fin de la portée), l'appel de suppression ira à un tas différent de celui où il était nouveau: ed, et les accidents s'ensuivent. Par conséquent, pour la compatibilité STL entre les DLL sur Windows, le même compilateur doit être utilisé.

Si une DLL expose une API où elle peut toujours libérer sa propre mémoire, il n'y a pas de problème. (c'est-à-dire penser COM, ou quelque chose de similaire mais moins hideux).

Il pourrait également y avoir des incompatibilités ABI, mais je ne suis pas si sûr de ceux-ci. Au fil des ans, j'ai surtout été mordu par des problèmes d'allocation/de libération de mémoire.