использование std :: string с Qt вызывает ошибку во время выполнения при уничтожении - PullRequest
0 голосов
/ 25 февраля 2010

У меня есть приложение Qt, которое использует другую библиотеку, где вывод функции - std :: string вместо QString.

Итак, в моей программе у меня есть метод

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

Когда моя внешняя библиотека возвращает непустую std :: string, все работает нормально. Но когда возвращается пустая строка std :: string, приложение вылетает в конце области. Я догадался, что это связано с уничтожением объекта std :: string (?).

Преобразование в QString работает нормально, даже с пустой строкой std :: string.

Может кто-нибудь сказать мне, почему это происходит, и как избежать этой ошибки во время выполнения?

(В других темах некоторые люди обсуждали смешивание библиотек отладки и выпуска, но я не думаю, что сделал это.

Ответы [ 3 ]

1 голос
/ 14 декабря 2011

Решение состоит в том, чтобы убедиться, что ваша версия Qt скомпилирована с тем же компилятором, который вы используете для своего приложения.

В моем случае я скачал Qt 4.7.3, который был предварительно собран с VS2008. Когда я перешел на VS2010, toStdString вызывал сбой моего приложения. Я также получил бы некоторые другие странные ошибки со строками STL.

Итак, просто сконфигурируйте ваш выпуск и заново создайте его с помощью компилятора VS2010.

0 голосов
/ 14 декабря 2011

То, что вам нужно искать, используя Dependency Walker (который предлагает Патрик), это разные версии библиотек времени выполнения msvc (msvcrt и друзья), и если они используются разными библиотеками DLL, которые обмениваются памятью между ними.

Это важная часть, так как куча хранится в dll времени выполнения, каждая среда выполнения будет иметь свою собственную кучу (т.е. для 2008, 2010, 2005).

Таким образом, если вы выделите память в одной dll (скажем, путем создания std :: string с более чем 16-ю символами) и отправите ее в другую dll, где она умрет (в конце области видимости), вызов delete будет перейдите в другую кучу, отличную от той, где она была новой: ed, и последует сбой.

Таким образом, для совместимости STL между библиотеками DLL в Windows должен использоваться один и тот же компилятор.

Если DLL предоставляет API, где она всегда может освободить свою собственную память, такой проблемы нет. (то есть, думаю, COM или что-то похожее, но менее отвратительное).

Могут также быть несовместимости ABI, но я не уверен в них. На протяжении многих лет меня больше всего беспокоили проблемы с выделением / освобождением памяти.

0 голосов
/ 25 февраля 2010

Используйте «средство обхода зависимостей», чтобы увидеть, на какие библиотеки DLL полагаются ваше приложение (и внешняя DLL, и DLL QT).

...