DLL (Visual Studio 2008 コンパイラ) から (特殊化された) テンプレート クラスを使用すると、リンカー エラー - 未解決のシンボル - が発生します。ここ Stackoverflow でも説明されている「明示的なテンプレートのインスタンス化」トリックを使用しようとしましたが、うまくいきませんでした。私はそれを非常に単純な再現可能な例に分解しました:
次の内容のヘッダー ファイル「MyTemplates.h」(およびこのヘッダー ファイルを単に含むコードを含まないソース ファイル「MyTemplates.cpp」) を含むダイナミック ライブラリ (DLL) 「MyTemplates.lib」があります。
template <class T>
class A
{
public:
A()
{ int x = 7; }
};
template <class T>
class B : public A<T>
{
public:
B()
{}
};
// do explicit template instantiation for classes A<int> and B<int>
// macro 'MYTEMPLATES_API' is defined in the usual way as:
//#ifdef MYTEMPLATES_EXPORTS
// #define MYTEMPLATES_API __declspec( dllexport )
//#else
// #define MYTEMPLATES_API __declspec(dllimport)
//#endif
template class MYTEMPLATES_API A<int>;
template class MYTEMPLATES_API B<int>;
これで、ファイル「Util.h」と「Util.cpp」を含む別の動的ライブラリ「UserLibary」(「MyTemplates.lib」にリンク) ができました。ファイル「Util.h」は次のとおりです。
#include "MyTemplates.h"
class UserClass
{
public:
UserClass();
public:
A<int> bla;
B<int> blubb;
};
ファイル「Util.cpp」の内容は次のとおりです。
#include "Util.h"
UserClass::UserClass()
{
}
問題は、ライブラリ 'UserLibrary' が正常にコンパイルされることですが、次のように 2 つのリンカー エラーが発生します。
1>Util.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall B<int>::B<int>(void)" (__imp_??0?$B@H@@QAE@XZ) referenced in function "public: __thiscall UserClass::UserClass(void)" (??0UserClass@@QAE@XZ)
1>Util.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall A<int>::A<int>(void)" (__imp_??0?$A@H@@QAE@XZ) referenced in function "public: __thiscall UserClass::UserClass(void)" (??0UserClass@@QAE@XZ)
そのため、リンカは、クラスA<int>
およびのデフォルト コンストラクタのシンボルを見つけることができませんB<int>
。なぜこれが可能で、どうすればこれらのリンカ エラーを取り除くことができますか? クラスの明示的なテンプレートのインスタンス化A<int>
とB<int>
(ファイル 'MyTemplates.h' 内) がこれを解決すると思っていましたが、残念ながらそれは役に立たないようです - または間違った方法で使用していますか? 私のコンパイラは Visual Studio 2008、オペレーティング システムは Windows 7 64 ビット、コードは 64 ビットでコンパイルされています。