質問

次のような静的メソッドを持つクラスがあります:

class X {
    static float getFloat(MyBase& obj) {
        return obj.value();  // MyBase::value() is virtual
    }
};

MyBaseをサブクラス化するMyDerivedのインスタンスで呼び出しています:

MyDerived d;
float f = X::getFloat(d);

Xを含むobjファイルを実行可能ファイルにリンクすると、すべてが期待どおりに機能します。 3.14を取得する予定であれば、取得します。

X.objファイルを含む.libを作成し、.libにリンクすると、壊れます。 getFloat()を呼び出すと、 -1。#IND00 が返されます。これは、ここで何が間違っているのかを伝えるべきセンチネル値のタイプですか?

objを直接リンクするのではなく、libをリンクするときに何か違いはありますか?

コンパイラの警告やエラーは表示されません。

編集:
Windows XP Pro SP3でVisual Studio 2005を使用しています。古いファイルをリンクしていないことを確認するために、value()メソッドを新しいvalue2()メソッドに複製し、代わりに呼び出しました。動作は同じでした。

編集#2:
そのため、デバッガーで呼び出しをトレースすると、value()メソッドにはまったく入っていないことがわかります。代わりに、異なる(無関係な)メソッドに入ります。これにより、vtableが破損していると思われます。私が見ている行動は、他の問題の副作用であるに違いないと思います。


解決しました!(Vladに感謝)
投稿したコードからは明らかではありませんでしたが、1つの定義規則(ODR)に違反していたことがわかりました。 これは、Visual C ++の連中による素晴らしい記事で、問題とそれを追跡する1つの方法を説明しています。 / d1reportSingleClassLayout コンパイラフラグは素晴らしい学習ツールです。

2つの異なるプロジェクトでMyBaseとMyDerivedのクラスレイアウトをダンプすると、呼び出しコードとライブラリコードの違いが見つかりました。ヘッダーファイルに #ifdef ブロックがあり、対応する #define ステートメントがメインプロジェクトのプリコンパイル済みヘッダーにありましたが、サブプロジェクト(ライブラリ)。プリプロセッサマクロがどれほど悪であると思いますか?

とにかく、他の誰かに役立つかもしれないので、私はこのものだけを投稿しています。 この質問も非常に役に立ちました。

役に立ちましたか?

解決

この問題は、 MyDerived クラスの異なる定義(つまり、 .h <の異なるバージョン)でlibと実行可能ファイルがコンパイルされた場合に発生します/ code> / .hh / .hpp MyDerived を宣言するファイル。プロジェクトを完全にクリーンアップして再構築します。これを除き、異なるコンパイラオプションおそらく責任を負う可能性がありますが、それはいくぶんありそうもないことです。

すべてをゼロから再構築しても問題が解決しない場合は、ライブラリの getFloat 内にダミーの MyDerived オブジェクトをインスタンス化して問題を解決します。デバッガを使用して、ダミーの MyDerived (ライブラリにインスタンス化されている)の vtable MyDerived vtable を比較します。 >パラメータとして渡されたオブジェクト参照(実行可能ファイルでインスタンス化されます。)すぐに何かが目につきます。

他のヒント

libは単なるコンテナであるため、両方のケースで同じ.objファイルをリンクしている場合、ブライアンが言うように、違いはない(できない?)

注目すべき点の1つは、MyBaseの定義を変更した場合、ライブラリとそれを使用するコードの両方を再コンパイルする必要があることは明らかです。たとえば、値メソッドの前にMyBaseに新しい仮想メソッドを追加した場合、値のvテーブルオフセットが異なるため、ライブラリが混乱します。

違いはないはずです。含めている.hファイルが、リンク先の.libに正確に対応していることを確認してください。古い.libファイルにリンクしている可能性があります。

Visual Studioを使用している場合、.libファイルを明示的に指定する代わりに、プロジェクトを右クリックして、.libプロジェクトへの依存関係を設定するだけです。そうすれば、正しい.libファイルが使用されていることを確認できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top