15

vs2008 で C++ スタティック ライブラリをコンパイルしています。ソリューションには、lib を使用するスタートアップ プロジェクトもあり、正常に動作します。

しかし、別のソリューションでライブラリを使用すると、実行時チェックに失敗します。「関数呼び出し全体で ESP の値が適切に保存されませんでした」 コードをステップ実行すると、関数 foo() がクラッシュの直前に代わりに bar() にジャンプしていることに気付きました。問題の関数は通常の関数であり、関数ポインターはありません。

何が起こっているのか、同じソリューションのライブラリを使用するとなぜ機能するのか、誰にも手がかりがありますか?

編集:それが役立つ場合、関数(メソッド)はクラスの一部です。

4

5 に答える 5

16

ここで明らかな出血を述べて申し訳ありませんが... オブジェクト (.o) ファイルとヘッダー (.h) ファイルが同期しなくなる前に、この種のことが何度も起こるのを見てきました。特に仮想メソッドに関して。

考慮してください: オブジェクトファイルはヘッダー付きでコンパイルされます:

class Foo { virtual void f(); };

ただし、ヘッダーは次のように変更されます。

class Foo { virtual void g(); virtual void f(); };

次のオブジェクト ファイルでは、クラスの vtable 内で f() が配置されている場所に関するコンパイラの想定は正しくありません。

多くの場合、単純に世界 (すべて!) を再コンパイルするだけで解決します。

于 2008-12-16T01:05:33.830 に答える
7

これはおそらく、ライブラリと呼び出し元がスタックレイアウトについて異なる考えを持っている、互換性のない呼び出し規約が原因です。

詳細については、MSDNを参照してください。

于 2008-12-15T13:06:21.130 に答える
2

リリース モードではなく、デバッグ モードでコンパイルしていることを確認してください。リリース モードでプログラムをデバッグしようとすると、デバッガから返されるデータは最適化のためにガベージになります。

于 2008-12-15T12:48:43.270 に答える
1

バイナリの構造体メンバーの配置(/ Zpコンパイラスイッチ)が異なっていたときに、そのようなことを見たのを覚えています。あなたもそれをチェックすることができます。

プロジェクト設定ではなく、#pragmapackを使用して設定する方が安全です。

于 2008-12-15T13:10:04.320 に答える