2

他のC++プロジェクトで一般的に使用されているC++クラスライブラリプロジェクトがあります。クラスライブラリプロジェクト内でクラスを使用できるようにするために、以下の例のようなヘッダーファイルを作成しました。

#pragma once
#ifdef MYLIB
# define MYLIB_EXPORT __declspec(dllexport)
#else
# define MYLIB_EXPORT __declspec(dllimport)
#endif

クラスライブラリプロジェクト内にテンプレートクラスを作成するまでは問題ありません。問題は、テンプレートクラスをエクスポートできないことです。

MyClass.h

template<class T>
class MYLIB_EXPORT MyClass
{
    void myMethod();
    // ...
}

template<class T>
void MyClass::myMethod()
{
    // ...
}

この場合、「dllimport関数の定義は許可されていません」というコンパイルエラーが発生します。私は何が問題を引き起こしているのかを知っており、それを理解しています。クラスライブラリプロジェクトを使用する他のプロジェクトは、MYLIB_EXPORTキーワードを__declspec(dllimport)に変換します。したがって、彼らはMyClassのメソッドがDLLで定義されることを期待しています。ただし、コンパイラはヘッダー内の定義を確認します。

この状況を克服し、クラスライブラリプロジェクト内で定義されているテンプレートクラスをエクスポートするにはどうすればよいですか?

4

2 に答える 2

4

インスタンス化されていないテンプレートは直接コンパイルできません。これらはコード ジェネレーターであるため、実際にはインスタンス化された場合にのみバイナリ命令に変換されます。このため、テンプレートを「通常の」関数/クラスであるかのように「バイナリ形式で」エクスポートすることはできません (一方、少なくとも理論上は、テンプレートのインスタンス化をエクスポートできます)。

簡単に言えば、ライブラリ クライアントによってインクルードされるように、テンプレートをヘッダーに残すだけです。

.cppこれが、テンプレートをヘッダーに保持し、通常はそれらの実装をファイルに分離しない正確な理由であることに注意してください。

于 2012-12-04T14:45:37.610 に答える
0

MYLIB_EXPORTテンプレートクラスのステートメントを削除するだけです。次に、クラスの外部でクラス関数を定義できます (ただし、*.hヘッダー*.hppファイル内にはあります)。

MyClass.h

    template <typename T>
    class MyClass    // MYLIB_EXPORT removed
    {
        void myMethod();
        // ...
    };

    template <typename T>
    void MyClass<T>::myMethod()
    {
        // ...
    }

この問題が発生しました。久しぶりに、MYLIB_EXPORTを削除すると直ったことに気づきました。この回答が他の人の時間を節約することを願っています:-)

于 2013-04-12T14:15:36.733 に答える