2

create メソッドをエクスポートするテンプレート化されたファクトリ クラスを作成しようとしています。

template <typename T>
class ClassFactory
{
    _declspec(dllexport) static void* Create()
    {
        return new T;
    }
};

class Foobar : ClassFactory<Foobar>
{
    std::string foo;
};

このコードは正常にコンパイルされますが、 dumpbin /exportsの出力を見るとエクスポート テーブルに何も表示されません。

次のコードは、Create() を正しくエクスポートします。

class ClassFactoryBase
{
    _declspec(dllexport) virtual void* Create() = 0;
};

template <typename T>
class ClassFactory : ClassFactoryBase
{
    void* Create()
    {
        return new T;
    }
};

class Foobar : ClassFactory<Foobar>
{
    std::string foo;
};

ただし、Create() を静的にする必要があります。サンプル 2 は機能するのに、サンプル 1 は機能しないのはなぜですか? 静的テンプレート メソッドをエクスポートする方法はありますか?

4

2 に答える 2

2

コンパイラは、Create()関数が呼び出されないことを確認するため、コードを生成しません。機能させるには、次のようにテンプレートを明示的にインスタンス化する必要があります。

template class ClassFactory<Foobar>;

この行をソースに追加するだけです。これで、コンパイラはこの関数のコードを生成してエクスポートします。詳細については、MSDN の記事 - Explicit Instantiation (C++)を参照してください。

なぜ例 2 が機能し、例 1 が機能しないのかという他の質問に答えるために、派生クラス Foobar を詳しく見てみましょう。このクラスには仮想関数があるため、コンパイラは vtable を生成する必要があります。vtable に入力するには、コンパイラは Create() のアドレスを知る必要があります。これは、基本クラス テンプレートから暗黙的にインスタンス化される場合です。この関数のコードは、要求に応じて生成され、DLL にエクスポートされます。これが、例 2 が機能する理由です。

于 2012-05-23T10:36:22.637 に答える
0

インスタンス化されていないテンプレート メソッドはコンパイルされていないため、テンプレート メソッドを DLL からエクスポートする方法はありません。あなたの例はDLL自体ではあまり機能しません.ヘッダーファイルは、すべてを機能させるものです。

于 2012-04-11T09:01:07.970 に答える