2010-02-25 94 views
0

我有一個Qt應用程序,它使用另一個函數輸出爲std :: string而不是QString的庫。與Qt使用std :: string會導致破壞時的運行時錯誤

所以在我的節目,我有一個方法

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

當我的外部lib中返回一個不空的std :: string一切工作正常。 但是,當返回一個空的std :: string時,應用程序在作用域的末尾崩潰。我猜想,這與破壞std :: string對象(?)有關。

即使使用空的std :: string,轉換爲QString也能正常工作。

有人可以告訴我爲什麼發生這種情況,以及如何避免這種運行時錯誤?

(在其他線程一些人討論調試的混合和釋放庫,但我不認爲我已經做到了。如何找出BTW?)

回答

0

使用「依賴學步車」,看看哪個DLL的您的應用程序(以及外部DLL和QT DLL)依賴。

+0

好的.. 我這樣做,它只使用標準的Qt庫+我的external.dll,它再次使用了很多東西。我真的不知道這裏是否有什麼不對,但看起來不像。 – Magus

1

解決方案是確保您的Qt版本使用與您的應用程序相同的編譯器進行編譯。

就我而言,我下載了使用VS2008預建的Qt 4.7.3。當我轉移到VS2010時,toStdString導致我的應用程序崩潰。我還會用STL字符串得到一些其他奇怪的錯誤。

因此,只需配置您的版本,然後使用VS2010編譯器重新制作。

0

你需要使用的Dependency Walker(其中帕特里克建議)爲看都是不同版本的MSVC運行時庫(MSVCRT和朋友),而如果它們是由不同的DLL的發生之間交換內存使用他們。

這是至關重要的部分,因爲堆保存在運行時DLL中,每個運行時都會有它自己的堆(即vs 2008,2010,2005)。因此,如果你在一個dll中分配內存(比如說創建一個超過16個字符的std :: string),並將它發送到另一個它死的地方(在範圍的末尾),delete調用將會到達一個不同的地方,而不是從新的地方開始:ed,然後崩潰隨之而來。

因此,對於跨Windows上的DLL的STL兼容性,必須使用相同的編譯器。

如果一個DLL公開了一個API,它總是可以釋放它自己的內存,那麼就沒有這樣的問題。 (即認爲COM,或類似的東西,但不那麼可怕)。

也可能存在ABI不兼容性,但我不太確定那些。多年來,我一直被內存分配/釋放問題困擾。

相關問題