とりあえず、DOC, VIEW を外部のDLLとして実装してみます。
ここからサンプルプロジェクトをダウンロードできます
MFCプロジェクトを新規作成した直後に DOC / VIEW クラスに分離したり、これから新規に作成する DOC / VIEW クラスを外部DLLとして実装するのは非常に簡単です。
まず、クラスのエクスポートのやり方ですが、あるクラスを外部DLLとして実装するための手段はかなり昔から提供されています。
class __declspec( dllimport ) CClassName
__declspec( dllimport ) 修飾子をヘッダ内のクラス定義部分に付加することにより、このクラスの実体は外部モジュールとして提供されているとコンパイラに伝えることができます。
class __declspec( dllexport ) CClassName
__declspec( dllexport) 修飾子をヘッダ内のクラス定義部分に付加することにより、このクラスは外部にインターフェースを興起しているとコンパイラに伝えることができます。
つまり、クラスを外部に公開したい場合には dllexport、外部で公開されているクラスを使用したい場合には dllimport をクラス定義部分に修飾子として付加すればいいわけです。
たとえば、 CMyObject クラスの宣は以下のようになります。
このクラスを外部に公開したい場合には
class __declspec( dllexport ) CMyObject
{
....
....
};
外部で公開されたクラスを取り込みたい(外部モジュールがこのクラスを公開している必要があります)場合には
class __declspec( dllimport ) CMyObject
{
....
....
};
となります。
さて、必要な予備知識はそろったので、VC++ の AppWizard を使って作成したデフォルトの SDI アプリケーションの CDocument, CView クラスを外部DLLに移してみたいと思います。
やらなければいけないことは
1.新しいDLLプロジェクトをMFC拡張DLLとして作成する
2.CDocument, CView クラスの CPP ファイルをEXEファイルから削除し、今作ったDLLファイルに CPPとHを追加する
3.若干のソースの修正
の3つです。
1、2は飛ばします。
ここでは、Document クラスを CMyDocument, Viewクラスを CMyView として説明します。
まず、現在コンパイル中のプロジェクトがEXE側なのかDLL側なのか識別するための プリプロセッサマクロを定義します。
stdafx.h に追加しても、プロジェクトの設定の追加マクロの設定で追加してもかまいません。
EXE側に
DLL 側に
というマクロを追加します。
これは、Document, View の宣言部分をコンパイルする際に、現在 EXE をコンパイルしているのか、あるいは DLL をコンパイルしているのかをコンパイラに知らせるために使います。
次に、CMyDoc.h CMyView.h の クラス宣言の直前に以下の行を追加します
さらに、クラスの宣言部分を以下のように変更します
class _EXPORT_CLASS_ CMyDoc ....
class _EXPORT_CLASS_ CMyView ....
そして、 ソースコード内で、MyDoc.h MyView.h を include している箇所の参照パスを適切に変更してください。
最後に、EXEファイルのプロジェクトに DOC/VIEW の実体が存在するDLLのLIBファイルを追加します。
DLLをコンパイルし、LIBファイルを作成したら、EXEファイルのプロジェクトに LIB を追加し、コンパイルしてください。
DLLよりも先にEXEをコンパイルしたり、LIBを追加しないまま EXEをコンパイルすると、リンクエラーが出るはずです。