前回作ったDLLを、実際に使ってみましょう。今回の話は、別に自作DLLだけではなく、API系のDLLやMFC系のDLLを使う場合にも言えることなので、結構重要だったりします。
|
出力されたファイルの確認
DLLを作製したときに、いろんなファイルが生成されたと思います。そのファイルを確認してみましょう。
DLLファイル(*.dll)は、作製した関数やクラスが入っているファイルです。実行時に、Exeはこのファイルにリンクします。逆に言えばExeファイルを作るときには必要ないファイルでもあります。
基本的に重要なのはこの4ファイルです。ではまず、Exeファイルのビルドに必要なライブラリファイル、そして関数の宣言が書かれたヘッダーファイルについて見ていきましょう。 |
検索ディレクトリの指定
DLLを使うアプリケーションを作る時に必要なファイルは「ヘッダーファイル」と「ライブラリファイル」です。もちろん前前回のように「ライブラリを使わない方法」を使えば両方ともいりませんが、自作DLLでそれは難しいことは、前回を読めば分かると思います。
さて、この2ファイルをどうやって使えばいいのか、順に見ていくことにしましょう。
このどちらを使ってDLLのヘッダーファイルをインクルードするかは、DLLによって違ってくると思います。
では、どうやって自作DLLのヘッダーファイルを< >でインクルードするのかというと、「検索ディレクトリ」にこのヘッダーファイルがあるフォルダを追加すればいいのです。 |
どこでインクルードするか
さて、では実際にインクルードしてみましょう。Exeファイルの側で#include <Func.h>のようにインクルードすればOKです。 ただし、注意すべき点がふたつあります。
まずひとつは、どのファイルでインクルードするかという問題です。
ところがこれにはデメリットもあります。
このふたつのメリットとデメリットを考えて、DLLが完成するまではソースコードで、完成したらStdAfx.hでインクルードするのがいいでしょう。 |
「標準インクルードファイル」の作製
もうひとつの問題は、どのファイルをインクルードすべきかという点です。前回作製したDLLの場合、__declspec(dllexport)を用いてエクスポートした場合には、Func.hにはDLL_EXPORTが用いられているのでDefs.hもインクルードしなければなりません。また、仮にFunc.hでCArrayなどを使っていればafxtempl.hをインクルードする必要が出てきます。 つまりどういうことかというと、Exeの側で、インクルードするファイルを決めなければならないということです。DLL側で必要としたヘッダーファイルは、Exe側でも必要になるということになります。が、DLLのインクルードは、当然ソースファイルや、StdAfx.hに書いてあったりして、分かりにくい場合が多いでしょう。
そこで、DLL側に「このヘッダーファイルをインクルードすればばっちり大丈夫!」というファイルを作ってしまいましょう。 |
#ifndef __STDHEAD_H__
#define __STDHEAD_H__
// ライブラリファイルを読み込みます。
#pragma comment(lib, "Test.lib")
// ヘッダーファイルを読み込みます。
#include <Defs.h> //マクロ用ファイル。
#include <Func.h> //関数のプロトタイプ宣言が入ったファイル。
#endif //__STDHEAD_H__
このように、DLLの側で「必要なファイルをインクルードしてくれるヘッダーファイル」を作っておくと、とても便利です。例えばDLLの仕様が変わって、定義ファイルを使うことになった場合には、Defs.hのインクルードをコメントアウトすればいいわけです。Exe側は、あとでリビルドするだけで済むというわけです。
ただ、ファイル名だけは気を付けてください。先ほど説明したとおり、ヘッダーファイルは「検索リスト」の上の方のフォルダにあるファイルが優先されます。システムフックなどの、特定のExeでしか使わないDLLでは、特別な名前を使用した方が安全でしょう。
で、このファイルを作製したら、Exe側でこのファイルをインクルードしてください。それだけでDLLの機能をすべて使えるようになります。 |
ライブラリファイル
は、実はもうできちゃってます。 ライブラリファイルも、ヘッダーファイルと同じく「オプション」の「検索ディレクトリ」で登録されたフォルダから検索されます。ここでライブラリファイルのあるフォルダを登録しておけば、OKです。 あとは、ライブラリファイルを「検索リスト」に加えれば終了。#pragma comment(lib, "Test.lib")と、上の「これさえインクルードすればすべておっけー!」ヘッダーファイルに書き込まれていることを確認してください。 あと、ヘッダーファイルと同様、ファイル名の重複、検索ディレクトリの優先順位に気を付けてください。
ここまでで、Exeファイルの側は終了。あとはビルドしてしまえば、完成です。 |
DLLの位置と自動コピー
さて、DLLが完成し、Exeもビルドが終了した。じゃーデバッグテストで実行してみよう、とそのまえにDLLがどのフォルダにあるかを確認してください。 「DLLを使おう!!」で説明したように、DLLは特定のフォルダにある必要があります。Exeファイルやシステムフォルダ、ウィンドウズフォルダにDLLがなければ、Exeは異常終了します。これはデバッグ時でもなんでも同じです。 とゆーわけで、まだ置いていない場合には、作製したDLLを特定のフォルダにコピーしてください。システムフックのように特定のExeでしか使わないDLLはExeと同じフォルダに、MFCのように複数のアプリケーションから使用するDLLはシステムフォルダにコピーするのがいいでしょう。
でも、DLLをいちいちドラッグアンドドロップしてコピーするのは非常にめんどくさいです。ですが、これは簡単に解決します。これを自動化しましょう。 |
copy コピー元ファイル名 コピー先フルパス+ファイル名
となります。第1パラメータはプロジェクトファイルのあるフォルダです。ですから、ここではdebug\t_DLL.dllとなります。
第2パラメータは、コピー先のフルパスです。最後は、そのコピーするファイル名になります(つまり、ファイル名を変えてコピーすることもできるということです)。システムフォルダにコピーするのであればC:\windows\system\t_DLL.dllということになります。つまり、 |
copy debug\t_DLL.dll C:\windows\system\t_DLL.dll
のように書き込めばいいということです。もしこのDLLが、ひとつのアプリケーションからしか利用されないのであれば、第2パラメータをそのアプリケーションの実行ファイルのあるフォルダへとコピーすればOK。簡単ですね。
デバッグ版とリリース版のファイル名が同じ場合には、同じフォルダ(特にシステムフォルダ)にコピーされると混乱します。そういう場合には、デバッグ版のみのコピーをお奨めします。
さて、DLLのコピーも終了しました。これでもうデバッグもできますし、添付して配布することもできます。 |
プログラムデータベース
DLLの作成時に同時に生成されたファイルの中に、拡張子がpdbのファイルがあると思います。 このファイルはプログラムデータベースと呼ばれ、デバッグのための情報が書き込まれています。 プログラムデータベースには、DLLやExeのどの部分がソースコードのどの位置にあたるのかが書き込まれています。デバッガを実行すると、デバッガはこのファイルを読み込みブレークポイントの設定にあわせてソースコードを表示します。
ソースコードの検索は、3段階に行われます。
さて、もうひとつ疑問が残ります。それはプログラムデータベースファイルの検索です。ソースファイルと違い、「検索ディレクトリ」は使用しません。……イヤな予感のしたあなた、正解です。
以上のように、プログラムデータベースはフルパスが多く使われています。これはふたつの点で注意が必要です。 |
再配布するDLL
さて、DLLが完成した、Exeも完成した、デバッグも終了した、じゃぁホームページに掲載しましょう、という段階です。 まず必要なのが、自作DLLファイルとそれを使用するExeファイル。これは当然ですね。どちらもリリースバージョンだということを確認してください(「デバッグ」と「リリース」については次回説明する予定です)。 自作DLLが「拡張DLL」の場合、もう2ファイル、MFC42.dllとMSVCRT.dllの2ファイルが必要になります。前者はMFCが、後者はランタイム関数が入っているDLLです。
この2ファイルに関しては注意が必要です。まず、標準インストールのウィンドウズ95には入っていません。また、バージョンの問題もあります。MFC42.dllは、VCの4.2と5.0で使用されていますが、4.2に添付されたものは5.0で作られたExeやDLLとリンクできません。クラス等、追加されたものがあるからです。
ちなみに、ExeがどのDLLを使用しているのか簡単に調べる方法を解説しておきます。
もう一度書きます。「'*.dll' のシンボルを読み込みました」と書かれているDLLのリリースバージョンを配布してください。MFC42.dllのデバッグバージョンはMFC42d.dll、MSVCRT.dllのデバッグバージョンはMSVCRTd.dllです。で、配布するのはあくまでリリースバージョンですから。念を押すようですけど、くれぐれも注意してください。 |
プログラマーに公開する場合
同様に再配布する場合でも、アプリケーションとしてではなく、他のプログラマーが使えるようにDLLを公開したい場合もあるでしょう。 そういう場合、最低限必要なのは、リリースバージョンのDLLとライブラリファイル、そしてヘッダーファイルです。この3つはかならず配布してください。 でも、使ってくれる人のことを考えるのなら、やっぱり全部がいいでしょう。つまり、上の3つに加えて、デバッグバージョンのDLL&LIB、デバッグに必要なプログラムデータベース、そしてソースコード。
これらがあるとないとでは、デバッグのしやすさが全然違います。確かに、ソースコードを配布するのは勇気がいるかもしれません。でも、コードを見てもらい、使ってもらうことで自分のプログラムを鍛えてもらえるということは大きいことです。できるだけ、全部添付するようにしましょう。 |
まとめ
今回はちょっとまとまりがなかったかなーとゆー気がしないでもないです。「DLL関係の細かな注意」みたいになっちゃったかも。でも、DLL関係で分かりにくい部分は網羅したつもりです。どうでしょー。 次回は、関数ではなくクラスを作ってみます。また、「デバッグバージョン」と「リリースバージョン」のふたつのDLLを作る方法や、DLL側でデバッグする方法などを解説しようと思います。 |
(C)KAB-studio 1998 ALL RIGHTS RESERVED. |