3

vtable 内のオーバーロードされたメソッドの順序は、win32 コンパイラ間で常に同じですか?

問題: 「インターフェース」(データ メンバーを持たない純粋な仮想クラス) があります。これらは、さまざまなコンパイラからのポインターを介して使用できます (クライアントは、標準の c dll ファクトリ メソッドを呼び出してポインターを取得します)。これは、1 つのメソッドを除いて、さまざまなコンパイラ (例: borland で作成されたクライアント、Visual C++ で作成されたインターフェイス dll) で正常に機能します。このメソッドは、戻り値は同じですが、パラメータが異なります。このメソッドには 4 つのバージョンがあります。このメソッドを同じように呼び出しても、クライアントをコンパイルしたコンパイラによって異なる結果が返されます。アセンブラコードをざっと見てみると、vtable に別のオフセットがあるように見えました (私はアセンブラを読むのが得意ではありません)。

今はわかりません-原因を見つけたのでしょうか、それともボーランドがビジュアルスタジオとは異なるvtableを処理しているだけで、すべてが正しいので、他の場所を検索する必要があります.

よろしくお願いします。回答ありがとうございます。

トバイアス

4

4 に答える 4

1

vtable 内の関数の順序は、ABIでカバーされているものの 1 つです。残念ながら、ABI は C++ 標準の一部ではないため、異なるコンパイラが異なる ABI を使用することは非常に一般的です。

于 2010-07-14T06:08:00.987 に答える
1

数年前にこの問題に遭遇しました。現在、それをサポートするドキュメントはあまり見つかりませんが、vtable 内の関数が個別に宣言されていても、Visual Studio のグループがオーバーロードされていることを理解しています。これにより、ビルドが gcc では問題なく動作していましたが、Visual Studio ではクラッシュしていました。オーバーロードされた関数を回避する方法が見つからなかったため、最終的にはオーバーロードされた関数を削除しただけだと思います。

于 2011-01-19T16:57:34.757 に答える
1

考えられる原因は 2 つあります。クライアント コンパイラが予想とは異なるオーバーロードを選択しているか、別のコンパイラが別の vtable エントリにオーバーロードを配置しています。

渡す/期待するパラメーターは何ですか? 過負荷の解決が問題になる可能性はありますか?

vtable エントリの場合は、オーバーロードの名前を変更してみてください。

インターフェイスを宣言するときに、ターゲット コンパイラで利用可能な COM メカニズムを使用してみましたか? たとえばinterface、MSVC のキーワードを使用して、インターフェイス クラスに GUID を指定します。COM インターフェイスは、宣言された順序で vtable に関数を持つことになっているため、同じヘッダーを共有する場合、コンパイラ間で共通です。

于 2010-07-14T06:57:34.487 に答える
0

間違っているのはインデックスである必要はありません。vtableに完全に異なるサイズのエントリを含めることができます。彼らのABIが一致しない限り、何かが同じであるという保証はありません。彼らのABIが一致するとき、それは保証されます。

考えられるABIは、GCCおよびIntelのC++コンパイラで使用されるIA64abi、またはMicrosoftが導入したCOM相互運用機能です。

于 2010-07-14T10:08:29.577 に答える