using std::string with Qt causes run-time error on destruction
I have a Qt app that uses another library where the function output is std::string instead of a QString.
So in my program I have a method
void doSomething() {
...
std::string std_string = MyExternalLibraryThatReturnsSTLstring.getString();
QString myQString = QString::fromStdString(std_string);
...
process(myQString);
...
}
When my external lib returns a not-empty std::string everything works fine. But when an empty std::string is returned, the app crashes at the end of the scope. I guessed that has to do with destruction of the std::string object(?).
The conversion to QString works fine, even with an empty std::string.
Can someone tell my why this happens, and how to avoid this run-time error?
(In other t开发者_开发知识库hreads some people have discussed mixing of debug and release libraries, but I dont think that I have done that. How to find out btw?)
The solution is to make sure your Qt version is compiled with the same compiler you are using for your application.
In my case, I downloaded Qt 4.7.3 which was pre-built with VS2008. When I moved to VS2010, toStdString was causing my app to crash. I would also get some other strange errors with STL strings.
So, simply configure your release, and re-make it with the VS2010 compiler.
Use "dependency walker" to see on which DLL's your application (and the external DLL, and the QT DLL) are relying.
What you need to look using the Dependency Walker (which Patrick suggests) for is different versions of the msvc runtime libs (msvcrt and friends), and if they're used by different dll's that happen to exchange memory between them.
This is the crucial part, since the heap is kept in the runtime dll, each runtime will have it's own heap (i.e. for vs 2008, 2010, 2005).
So, if you allocate memory in one dll (say by creating a std::string with more than 16 or so characters) and send it to another dll where it dies (at the end of scope), the delete call will go to a different heap than from where it was new:ed, and crashes ensue.
So, for STL compatibility across DLLs on windows, the same compiler must be used.
If a DLL exposes an API where it always can free it's own memory, there is no such problem. (i.e. think COM, or something similar but less hideous).
There could also be ABI incompatibilities, but I'm not so sure about those. Over the years, I've mostly been bitten by memory allocation/freeing issues.
精彩评论