#pragma twice

KAB-studio > プログラミング > #pragma twice > 327 Version 15.27 DLL のまとめ

#pragma twice 327 Version 15.27 DLL のまとめ

前のページへ 表紙・目次へ 次のページへ

 Version 15.27
DLL のまとめ

さて、今回で DLL とか設定関係は終わりです
な、なんかやたらこまかかったよーな……
だね。この15章では、 Exe や DLL の中身について触れたからね
ひとつひとつはある程度分かるけど、全体となると結構複雑だったかも
じゃあ、もう一度ひとつひとつ見ていこうか
まず最初の Version 15.01 ( No.301 ) 〜 Version 15.02 ( No.302 ) は
コンパイルとリンクについてね
コンパイルはソースファイル単位、っていうことがまず重要
ビルドすると、だーっと全ファイルしちゃうもんね
このソースファイル単位っていうのは、インクルードファイルの話にも、
プロジェクトの設定の話にも継ながるから
あ! そか、プリコンパイル済みヘッダーのって、ソースファイル単位
だったもんね
そういうこと。コンパイル系の細かい設定も、ソースファイル単位ででき
るから
で、それをリンクで全部継なげるわけね
この辺が分かりにくい理由のひとつは、 VC++ で簡単にビルドできるから
かも。一度、ひとつひとつコンパイルしてリンクする、っていうのをすると
色々わかるんだけど
めんどくさー
まぁそうなんだけどね……
次の Version 15.03 ( No.303 ) 〜 Version 15.06 ( No.306 ) は、
インクルードファイルの話
重要なのは、インクルードファイルは本当にただファイルを読み込んでい
るだけなんだ、ってこと
なんてゆーか、いつもは関数宣言が入ってるヘッダーファイルを読み込む
だけってイメージだけど、そうじゃないってことよね
そういうこと。ソースファイルを読み込むことだってできるしね。だから
順番とかが重要ってこと
つか、もう少しこの辺便利にならないの?
他の言語では便利なんだけどね。それに、 C++ を下手に拡張されても、
って思うし
あー、改悪されちゃうとヤダね
本当に……本当にね……
……えっと、インクルードファイルの読み込みの順番とか関係とかって、
教わってもなんだか分からないんだけど
これは自分で実際に組んでみないとわからないかもね。次回からは、その
辺も見ていくから
次回? 次の章?
そう、少し総合的な部分を見ていくから、その時に複数のソースファイル
を使って、相互にヘッダーファイルを読み込むようなプログラムを組んでみ
るから
それって MFC でもできるでしょ
 MFC だと、最初に AppWizard が作ってくれたのを変えるのは難しいから
ね。一から作ってみた方が分かりやすいよ
難しそうだけど……
まぁ、もう火美ちゃんだってかなりプログラム組んできてるんだから
そりゃそうだけど
次のVersion 15.07 ( No.307 ) 〜 Version 15.08 ( No.308 ) は
スタティックリンクライブラリの解説でした
スタティックリンクライブラリ、って結局ほとんど使わない?
使わないことが多いね。スタティックリンクライブラリとして提供するく
らいならソースファイルごと提供することの方が多いし、 DLL なら、バグ
があっても DLL だけ入れ替えればいいからね
スタティックリンクライブラリを作る価値はない、と
でもオブジェクトファイルの理解が深まるし、 DLL と同じように
ライブラリファイルを使うから、勉強にはいいと思うよ
一度は作っとけ?
そういうこと
次の Version 15.09 ( No.309 ) 〜 Version 15.19 ( No.319 ) は、今回
の本命、 DLL ね
 DLL は、まず仕組みが難しいかな
 DLL はいいんだけど、ライブラリファイルが必要ってこととか、リンク
はライブラリファイルだけ必要とか、そういうとこが難しいかも
そういう情報って MSDN にははっきりと書かれてないしね
あとはやっぱりエクスポートかな、あれ難しい
そうそう、ひとつエクスポートについて触れ忘れたことがあったから、こ
こで解説します
え? ……結構重要なこと?
それなりに。まず、エクスポートする時の装飾名、って憶えてるよね
 Version 15.15 ( No.315 ) で出てきたね、ライブラリファイルに書かれ
た関数名、なんだよね
そうです。 DLL を使用するときには、ライブラリファイルの中からこの
装飾名を探して、関数が DLL にあることを確認します
うん、リンクするときにそうするんだよね
ここで重要なのは、関数名や引数を元に装飾名が作られて、その装飾名同
士で検索される、ってこと
どういうこと?
まず、 DLL でエクスポートするときに、関数名と引数を元に装飾名が作
られて、それがライブラリファイルに書かれます
うん
次に、使用する側の話。 Exe でインポートするときには、同じく関数名
と引数を元に装飾名が作られて、それを元にライブラリファイルを検索して
関数があるかどうか調べます
うんそうだね。何か問題あるの?
あるんです。装飾名の作り方、両方とも同じじゃないと
あ! 同じ関数名、同じ引数なのに、違う装飾名になっちゃうかもしれな
い、ってこと!?
そういうこと。具体的にどういう時に装飾名が異なるかというと、
ソースファイルが .c と .cpp とで異なります
え? 拡張子が違うだけで違うの?
拡張子が違うだけじゃないからね。 .c の時はC言語のソースファイルと
して、 .cpp の時はC++言語のソースファイルとしてコンパイルするから
言語が違う……
装飾名の時に説明したけど、C言語では同じ名前の関数はひとつだけだけ

C++言語の時は、オーバーロードがある!
そういうこと。だから装飾名が違うんです。実際、 DLLTestHard と
BuildTest の例で、 DLLTestHard の Func.cpp を Func.c にして、 
BuildTest でリビルドすると
あ、リンクエラー

リンク中...
Main.obj : error LNK2001: 外部シンボル 
    ""__declspec(dllimport) void __cdecl Output(char const *)" 
    (__imp_?Output@@YAXPBD@Z)" は未解決です
Debug/BuildTest.exe : fatal error LNK1120: 外部参照 1 が未解決です。
link.exe の実行エラー

このように、たとえば DLL が .cpp で Exe が .c の場合、または 
DLL が .c で Exe が .cpp の場合は、装飾名が異なるのでリンクできませ

まさに見つからないって感じね
だから、基本的には .cpp の方で統一するようにしてください
? 質問!
はい火美ちゃん
なんで .cpp の方で統一するの?
だって、そうしないと C++ の機能が全然使えないから。オーバーロード
できないし、クラスも使えないでしょ
あ、そういえば
実際、関数の動的リンクを使わない限り、エクスポートはクラス単位でし
て、 DLL も Exe も .cpp にする、っていうのが一番楽かな
もうひとつ質問!
はい火美ちゃん
ソースファイルの拡張子が違うとリンクできないって行ったけど、 API 
は .cpp でも .c でも使えるんじゃないの?
いい所に気付きました。実は Exe の側が .cpp でも .c でもちゃんと
リンクできる方法があるんです
あ、なんだあるんだ
でも今回はパス
えー?
それこそ、関数だけをエクスポートする DLL 、っていう場合にしか必要
ないから、これからそういう DLL を作ることはないと思うよ
んー、でもどんな感じか、だけでも教えて
そうだね、まず重要なのは、C言語側に合わせる、ってこと
 DLL でのエクスポートはC言語のにする、ってこと?
そういうこと。そうすれば、まず Exe の方が .c ならリンクできます
じゃあ、 .cpp の時は?
その場合のために、ヘッダーファイルの宣言部を extern というもので
囲みます。たとえばこんな感じに

// Func.h

extern "C"
{
DLLTESTHARD_API void Output( const char *p_pch );
}

 extern って初めて見た
この【extern "C"】っていうのは、囲んだ範囲をC言語形式にしてしまう
んです
C言語形式! なるほど、そうすればC言語の装飾名になるからリンクでき
るってことね
実際にはもう少し色々としなきゃいけないんだけど、簡単に説明するとこ
ういうこと。ただやっぱり、関数だけの DLL を、しかも動的リンク以外の
目的で作ることはないと思うから
必要ないってわけねー。まぁそうかもしれないけど
えと、話を戻して
あ、最後の Version 15.20 ( No.320 ) 〜 Version 15.26 ( No.326 ) は
【プロジェクトの設定】ダイアログだね
各設定について、駆け足だったけど説明しました
なんとなく全体的に分かったけど、細かい所となるとちょっと不安かも
でも実際、細かい所はほとんど必要ないよ。重要な設定は、こんなところ
かな

・【一般】-【Microsoft Foundation Class】
・【一般】-【出力ディレクトリ】
・【デバッグ】-【一般】-【デバッグ セッションの実行可能ファイル】
・【C/C++】-【コード生成】-【使用するランタイム ライブラリ】
・【C/C++】-【プリコンパイル済みヘッダー】
・【C/C++】-【プリプロセッサ】-【プリプロセッサの定義】
・【C/C++】-【プリプロセッサ】-【インクルードファイルのパス】
・【リンク】-【一般】-【出力ファイル名】
・【リンク】-【インプット】-【オブジェクト/ライブラリ モジュール】
・【リンク】-【インプット】-【追加ライブラリのパス】
・【ビルド後の処理】

あ、そんな多くないね。どれも DLL の時に使ったのだし
それに、最適化とかはむしろあまりいじらない方がいいしね。劇的に実行
速度が改善するわけじゃないから、そんなところをいじるくらいなら、
プログラムを修正した方がいいよ
確かにそうです……
さて、今回まではものすごく中の方について見ていきました
中?
ハードウェア寄りというか、すごく生っぽい話
なんとなく分かるような……
次回からは、外、プログラムについて見ていきます
プログラム?
そう。主にクラスを中心に、メンバ変数とメンバ関数、オーバーライドと
いったところを説明していきます
あー、そういえばその辺ってしっかりは教わってないかも。 MFC 使って
いた時になんとなく分かってた、って感じだし
その MFC を自分で作れるくらいには教えます
いや無理だから

/*
    Preview Next Story!
*/
というわけで次回からはクラスの説明に入ります
 DLL とかよりは簡単そうかな
また違った難しさがあるからどうかな
げ、そういうもんなんだ
憶えること細かくて大変かも
というわけで次回
< Version 16.01 クラスを作ってみよう! >
につづく!
ところであと何章?
17章で完結……かな
お、もうそこまで
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。