1

純粋仮想メソッドのみで構成されるクラスを宣言するC++ヘッダーがあります。そのヘッダーを使用する2つのDLLがあります(1つはそのインターフェイスを実装しています)が、コンパイル時にリンクされていません。一方のDLLは、もう一方のDLLを動的にロードし、実装されたインターフェイスのポインタをもう一方に渡します。これらのDLLは同じ仮想テーブル構造を共有していますか?

4

4 に答える 4

2

もちろん、クラスヘッダーは、正確な仮想テーブル構造を含む完全なクラス(ここでは、メモリ内のレイアウト、すべてがどのように配置されているか、実際のデータではない)を構築するのに十分です。

考えてみてください。各リンクオブジェクト(.cppファイル)は個別にコンパイルされ、共通のヘッダーファイルのみが含まれますが、コンパイル時に、コンパイラは仮想呼び出しを正しくルーティングするために仮想テーブルの正確な構造を知る必要があります。

ちなみに読み通す質問のDoozy...

于 2012-02-07T20:45:57.880 に答える
2

私が正しく理解していれば、あなたは次のようなものを持っています:

ああ

class A
{
public:
    virtual void foo()=0;
}

B.cpp

#include <A.h>

class B : public A
{
public:
    void foo()
    {}
}

C.cpp

#include <A.h>

void bar(A * a)
{}

したがって、をB.cpp実装するクラスがあり、 (のインスタンスで提供する)のインスタンスへのポインタを受け入れる関数があります。あれは正しいですか?AC.cppAB

もしそうなら、はい、これらはvtableを共有します。vtableは、クラスをコンパイルすることによって作成され、独自のvtableはまったくBありません。C.cpp

于 2012-02-07T20:49:10.543 に答える
1

あなたは安全です。

メソッドがに表示される順序はvftable、基本クラスの構造によって決まります。注意する必要があるのはそれだけです。ただし、これはコンパイラ固有であるため、dllの生成には同じコンパイラを使用してください。それらが下位互換性があることに依存しないでください(または少なくともドキュメントを確認してください)。

次のヘッダーがあると仮定します。

//header.h

class A
{
public:
    virtual void foo() = 0;
    virtual void goo() = 0;
};

そして、あなたはB.dll次のクラスを持っています:

class B : public A
{
public:
    virtual void foo() {}
    virtual void goo() {}
}

ここで、で、で作成されたオブジェクトであるX.dllへのポインタを受け取ります。ABB.dll

呼び出し

void test( A* a )
{ 
   a->foo();
}

を呼び出しB::foo()ます。

試してみることができる巧妙な実験の1つは、コンパイルすることです。コンパイルB.dllするheader.hときはX.dll、次のメソッドの順序を逆にしheader.hます。

//header.h

class A
{
public:
    virtual void goo() = 0;
    virtual void foo() = 0;
};

この場合、これを行うべきではありませんが、test()inへの同じ呼び出しX.dllでメソッドが呼び出される可能性がありますB::goo()。これは、ヘッダーX.dllに存在することを前提としているためです。vftableただし、これは未定義の動作です。この例を書いたのは、要点を説明するためです。

于 2012-02-07T20:51:48.357 に答える
1

これはすべてコンパイラに依存しますが、一般に、クラスが純粋な仮想であり、変換ユニットでメンバー関数が定義されていない場合、コンパイラは弱いシンボルvtableとしてを生成します。あなたの特定のケースでは、異なる翻訳単位は基本タイプに対して別々の正確に等しいsを生成し、リンカー/ローダーは他の弱いシンボルと同じように1つを除くすべてのシンボルを破棄します(テンプレート化された非インライン関数を考えてください) 。vtable

ただし、の生成はvtable標準化されていないことに注意してください。つまり、2つの異なるコンパイラまたはバージョンのコードを混在させると、ODR違反が発生する可能性があります。

于 2012-02-07T20:58:14.737 に答える