ども、こんばんわ~
寝不足で頭痛が酷いZAKIです

忙しくなってきましたよ~
ふ、ふふふwがんばるぜっw

ブログのネタがあれども、書いてる時間が無いっ

そろそろ今書いてるブログメンバーじゃ更新がきつくなってきましたw

1年生のあいつとか、2年生のあいつとか、書いてくれないかなぁ~?かなぁ~?
さて、今回のテーマは
「DLLにしてみよう!」です。
DLLって聞いたことあるでしょうか?
ダイナミックリンクライブラリ(Dynamic Link Library)の略なんですが、
これを使うと何がいいのか?
それは本編を見てのお楽しみw
サンプルソースはこちらっ
C++_DLLTestはクラスをDLLにしたものです。
dglib_DLLTestはdglibを使った関数をDLLにしました。
[0回]
さて、本編です
それで、えーと、なんでしたっけ?
あ、DLLにする利点でしたねw
いろいろあるんですが、僕が注目しているところは
「プログラム実行時に動的にコードを追加できる」ところですね。
つまり、
ゲームがexeの状態でもdllファイルを入れ替えるだけで
ソースコードの修正ができるんです。
しかも、開発中でもDLLはリンクするだけなので、
本体プログラムでのコンパイル時間が短縮できます。
実は後者のほうをよく利用してて、2年生になるとクラスやらライブラリやらでコンパイル時間が5分を超えることもありましたw

なので、DLLにしてせめて自分のソースの時間だけでも短縮しようとやったことがあります
実際本体にソースを追加する必要がなくなるので、かなり時間短縮できたと思います

ただ、不利点もやっぱりあります
DLLという形式にソースコードをまとめてしまうので、
ソースコードの修正に手間がかかります。
「ソースコード修正→DLL形式に出力」と言う流れになるんですよね
締め切り間近などは、そのままリーダーのパソコンの提出するソースに修正を加えたりしたくなりますが、DLLではそれができませんね

ただ、一人のパソコンに群がらずに一人こつこつと修正を続けられるということでもあります
さて、次は作り方ですね。
まず、VSのプロジェクトの作成方法が少し変わります
プロジェクトの種類はWin32プロジェクトでOKですが、
その後のアプリケーションウィザード画面で
「アプリケーションの設定→アプリケーションの種類」を「DLL(D)」にします。
追加のオプションは空のプロジェクトでかまいません

次はメインのソースですね。
書き方はmain()ともWinMain()とも違い、
DLLMain()関数になります。
サンプルソースのDllMain.cに書いてありますね
引数の詳細はMicrosoftのリファレンスを見てください
実は僕も詳しいことはわかりません
特に使うことがないので、普通にTRUEを返すだけでもOKだそうです

そして、もう一つ重要ななのが、DllHead.hファイルです。
中を見ると
#ifdef _DLL_EXPORT //_DLL_EXPORTがある場合
#define DLL_USE __declspec(dllexport) /* DLLを作る場合 */
#else //_DLL_EXPORTがない場合
#define DLL_USE __declspec(dllimport) /* DLLを使う場合 */
#endif
こんな感じのものが書いてありますねー
これはDLLで関数、クラスなどを出力するとき、またはDLLの中の関数、クラスなどを使うときに付けるものです

関数、クラス、どちらの場合も
名前の前に付けます
void DLL_USE kansu();
class DLL_USE kurasu { };
こんな感じですね。
あとはそれぞれ.c、.cppソースで
DllHead.hをインクルードする前に
#define _DLL_EXPORT
と書いてやるとDLLとして出力できます。
この場合、DllHead.hがインクルードされ、DllHead.hの中、
#ifdef _DLL_EXPORT
で、_DLL_EXPORTが既に定義されているかで
コンパイル時の処理を分岐します
こうしておくと、使うときに普通にインクルードしていれば、勝手に#elseのほうのdefineが定義されるので、楽チンです

あとは、そのままビルドします
微妙に警告が出てきますが、一応ビルドは成功するはずです
そうすると、プロジェクトの
Debugフォルダの中に
が、出来ています。
さて、次は作ったDLLを使っていきましょう。
今回の記事で扱うのは実はDLLでなく、LIBのほうです。
この場合は
静的リンクライブラリといいます。
動的リンクというのは、実はプログラムの中で関数などを途中で追加して、途中で破棄する行為のことをいいます
今回は一度入れて入れっぱなしにするので、それとはまた違います

詳しい解説はまた今度の機会にしましょう

さて、まずは使うための準備をしましょう
さっきのDLLプロジェクトから以下のファイルをコピーします。
-
.dllファイル
-
.libファイル
-
DllHead.h
-
DLLの中にある関数orクラスの宣言が書いてあるヘッダ
.dllファイル、.libファイルは
使用するプロジェクト(
dglibならcl2.bat)のあるフォルダへコピーしましょう

他のファイルはどこでもかまいませんが、基本.dllファイル、.libファイルのあるフォルダに置けば大丈夫でしょう
あとは、mainのソースファイルに
#pragma comment(
lib,"TestDLL.lib")
と入れて、他のヘッダファイルをインクルードしましょう。
これで普通に使えるはずです


さて、コレで以上ですが、ちゃんとできましたかね?
1年生など関数をDLLにして使う場合は特に問題ないのですが、
2年生などSTLテンプレートを使う場合は注意が必要です

詳しくは参考ページのリンクをはっておくのでそれを見てみてください
DLLの作り方参考
http://www.geocities.jp/ky_webid/win32c/057.html
MSDNのリファレンス
http://msdn2.microsoft.com/ja-jp/library/z4zxe9k8(VS.80).aspx
STLとDLL
http://lamoo.s53.xrea.com/develop/tips/dlltips.html
クラスとDLL
http://www2s.biglobe.ne.jp/~ragnarok/program/win32/class_of_cpp_in_dll.htm
ぶはーー時間がーーー

この記事を準備してたら半日とんでっちゃいましたw
今度から短めのをちょこちょこ出してく方法に変えるかもしれません
むしろ、更新する時間取れるか心配ですw
とりあえず、今回はこの辺りで。
あでゅー

ノシ
PR
COMMENT