0

関数出力が QString ではなく std::string である別のライブラリを使用する Qt アプリがあります。

だから私のプログラムにはメソッドがあります

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

外部ライブラリが空でない std::string を返すと、すべて正常に動作します。ただし、空の std::string が返されると、スコープの最後でアプリがクラッシュします。std::string オブジェクト (?) の破壊と関係があると思います。

空の std::string であっても、QString への変換は正常に機能します。

なぜこれが起こるのか、この実行時エラーを回避する方法を教えてもらえますか?

(他のスレッドでは、デバッグ ライブラリとリリース ライブラリの混合について話し合っている人もいますが、私はそれを行ったとは思いません。ところで、どうやって調べるのですか?)

4

3 に答える 3

1

解決策は、アプリケーションに使用しているのと同じコンパイラで Qt バージョンがコンパイルされていることを確認することです。

私の場合、VS2008 でビルド済みの Qt 4.7.3 をダウンロードしました。VS2010 に移行したとき、toStdString が原因でアプリがクラッシュしていました。また、STL 文字列で他の奇妙なエラーが発生することもありました。

したがって、リリースを構成し、VS2010 コンパイラで再作成するだけです。

于 2011-12-13T21:08:07.347 に答える
0

Dependency Walker (Patrick が提案) を使用して確認する必要があるのは、さまざまなバージョンの msvc ランタイム ライブラリ (msvcrt とその友人) であり、それらがたまたまメモリを交換する異なる dll によって使用されている場合です。

ヒープはランタイム dll に保持されるため、これは重要な部分です。各ランタイムには独自のヒープがあります (つまり、vs 2008、2010、2005 の場合)。

したがって、1 つの dll にメモリを割り当て (たとえば、16 文字以上の std::string を作成することによって)、それを別の dll に送信すると (スコープの最後で)、delete 呼び出しが実行されます。 new:ed された場所とは異なるヒープになり、クラッシュが発生します。

そのため、Windows 上の DLL 間で STL の互換性を保つには、同じコンパイラを使用する必要があります。

DLL が常に自身のメモリを解放できる API を公開している場合、そのような問題はありません。(つまり、COM か、似たようなものを考えてみてください)。

ABI の非互換性もある可能性がありますが、それについてはよくわかりません。何年にもわたって、私は主にメモリの割り当て/解放の問題に悩まされてきました。

于 2011-12-13T21:33:23.870 に答える
0

「依存関係ウォーカー」を使用して、アプリケーション (および外部 DLL、QT DLL) が依存している DLL を確認します。

于 2010-02-25T11:03:17.027 に答える