はじめまして、よろしくお願いします。
開発ツール:VisualC++Toolkit2003
題名だけでは分かりづらいので、まず問題に至る過程を書きます。
まず最初は、DLLを作成するプロジェクト(仮名 DllProject1)をやってました。
そしてこの中にはクラステンプレート(仮名 ClassTemplate)も含まれていました。このクラステンプレートはヘッダにすべての処理を書いていたので__declspec(dllexport)はいらないと思ってました。
ところが問題が生じました。それはDllProject1で作ったDLLを利用する新たなDLL作成プロジェクト(仮名 DllProject2)をやっていたときです。DllProject2には、ClassTemplateをメンバに持つクラス(仮名 ClassUseTemplate)があります。メンバに持つというのは
ClassTemplate<int> classTemplateInt;
のような、メンバ変数を持っているということです。
コンパイラは警告(C4251)を出しました。下のURLに説明があります。
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vccore/html/C4251.asp
継承はしてませんが利用しているからでしょうか、とにかく対処方を考えました。
まず、思いついたのは以下の方法です。
#if defined(_WINDLL)
#define export_template __declspec(dllexport)
#else
#define export_template
#endif
つまりDLL作成時にはClassTemplateに__declspec(dllexport)が付き、それ以外は何も付かないという方法です。これによってDllProject2は完成できました。
しかしうまくいきませんでした。今度は普通のアプリケーションを作成するプロジェクト(ApplicationProject1)をやったときです。ApplicationProject1はDllProject1とDllProject2のDLLを利用します。
当然警告C4251がでました。DllProject2のClassUseTemplateクラスがClassTemplateを利用しているからです。
すなわち、DllProject1のみを利用するアプリケーションプロジェクトでは
class ClassTemplate{省略};
とならなければいけませんし、
DllProject1とDllProject2両方を利用するアプリケーションプロジェクトでは
class __declspec(dllexport) ClassTemplate{省略};
とならなければいけないのです。
<ここまでの文で間違った認識があれば教えてください>
こうなると#ifや#define等を複雑に駆使しないとできない気がします。一応、複雑でわかりにくい方法でやってみました。が、これはDLLの利用者側で気をつけなけえればならないような事があり、とても実用できません。
そもそも、もっと簡単な解決法はないでしょうか。長文になりすいません。
どなたか、解決法がわかるかた教えてください。お願いします。
MFC拡張DLLであれば、これに該当しますかね?
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vccore/html/_core_extension_dlls.asp
私はこの情報を元に、いろいろ検索して解決しましたが。
ご参考までに・・
以上。
オショウさん返信ありがとうございます。
MFCは使っていません。
一つ思いついた方法があります。
template<typename type>class __declspec(dllexport) ClassTemplate{};
クラステンプレートを常に__declspec(dllexport)で定義する方法です。
少なくとも
> 一応、複雑でわかりにくい方法でやってみました。
これよりは大幅に読みやすいコードで済みました。
一応力技で解決できました。
オショウさん返信ありがとうございました。
ツイート | ![]() |