クラステンプレートをexportする時の__declspec(dllexport)記述

解決


michi  2005-11-10 05:11:33  No: 59526

はじめまして、よろしくお願いします。
開発ツール: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の利用者側で気をつけなけえればならないような事があり、とても実用できません。

そもそも、もっと簡単な解決法はないでしょうか。長文になりすいません。
どなたか、解決法がわかるかた教えてください。お願いします。


オショウ  2005-11-10 06:10:46  No: 59527

MFC拡張DLLであれば、これに該当しますかね?
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vccore/html/_core_extension_dlls.asp

私はこの情報を元に、いろいろ検索して解決しましたが。

ご参考までに・・

以上。


michi  2005-11-10 08:21:05  No: 59528

オショウさん返信ありがとうございます。
MFCは使っていません。

一つ思いついた方法があります。

template<typename type>class __declspec(dllexport) ClassTemplate{};

クラステンプレートを常に__declspec(dllexport)で定義する方法です。
少なくとも
> 一応、複雑でわかりにくい方法でやってみました。
これよりは大幅に読みやすいコードで済みました。

一応力技で解決できました。
オショウさん返信ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加