疑問解決(dll)

2007/6/21

Windowsに欠かせないdllを解説します。

・概要

 dllとは、ダイナミックリンクライブラリ(Dynamic Link Library)のことです。
 対照的に、スタティックライブラリもあり、拡張子libとなります。

 スタティックライブラリは、コンパイルする時点でソフト(Exe)の内部に組み込まれます。
 そのため、開発者でなければ、見る機会は少ないと思います。
 それに対してdllは、実行環境と共に配布されます。
 これは、ソフトが動作中にdllソフトを使用します。

 どういう利点があるかというと、3点ほど考えられます。
 まず1点目。
 容量を節約できます。
 少し大げさですが、ライブラリが10MBのサイズだったとします。
 このライブラリを利用するソフトが10本あったとします。
 スタティックライブラリで作成すると、全てのソフトに組込む必要があるので、
 このライブラリだけで10MB×10本=100MBの容量が必要です。
 これをdllにすると、10MBですみます。

 次に2点目。
 ライブラリを更新する作業が楽チンです。
 スタティックライブラリで開発している場合、ライブラリがバージョンアップすると、
 それを使っているソフトは、全て作り直しをしなければ新しいライブラリを使用できません。
 しかし、dllであれば、dllファイルを置き換えるだけで、
 それを利用しているソフトは最新のライブラリを使用できます。

 最後に3点目。
 使用メモリ量を節約できます。
 基本的にWindowsのソフトは、書換え不可のプログラム部分と書換え可のデータ部分からなります。
 そして同じソフトを2つ起動した場合は、Windowsはプログラム部分を共用します。
 これをライブラリに当てはめると、
 同じライブラリを使用しているソフトが2本あるとします。
 この2本のソフトを起動した場合、ソフトのプログラム部分は当然別物なので2本分確保されます。
 スタティックライブラリを組み込んでいる場合は、同じライブラリでも別々にメモリを確保します。
 しかしdllの場合は、メモリを共有するためメモリを節約できます。

 以上のように複数のソフトから利用するライブラリはdllで作るのが良いです。

・用語週

 

用語解説
dllエントリポイント

下記の条件で呼び出される関数。
 ・dllがプロセスのアドレス空間に接続したとき(DLL_PROCESS_ATTACH)
 ・dllがプロセスのアドレス空間から切り離されたとき(DLL_PROCESS_DETACH)
 ・プロセスがスレッドを作ったとき(DLL_THREAD_ATTACH)
 ・スレッドが正常に終了したとき(DLL_THREAD_DETACH)

dllを作成する際は、明示的にエントリポイントを作る必要はありません。
エントリポイントが無い場合は、コンパイラが自動でエントリポイントを作成します。
(開発環境によっては作らないかも)

また、開発環境によってエントリポイントは違います。
 VisualC++の場合・・・DLLMain
 BorlandC++Builderの場合・・・DLLEntryPoint

インポートライブラリdllを作成すると、dllファイルの他にlibファイルもできます。
このlibファイルをインポートライブラリといいます。
インポートライブラリとインクルードファイルを、
開発プロジェクトに組込むと、
スタティックライブラリと同様の開発スタイルで良いため、
開発が簡単になります。
dllで外部に公開する関数は、
宣言の際「__declspec(dllexport)」をつける必要があります。
そして呼ぶ側は、「__declspec(dllimport)」をつける必要があります。

インポートライブラリを使用しない場合は、
 ・LoadLibrary関数
 ・GetProcAddress関数
 ・FreeLibrary関数
を使用して開発する必要があります。
マングリング

C++のコンパイラは、関数名(メソッド名)に修飾文字をつけます。
リンカは修飾された関数名を使ってリンクします。
この、関数名を修飾することをマングリングといいます。
また、反対の動作をデマングリングといいます。

これは、オーバーロード(同名で引数が違う関数)があるため、
関数名だけでは対応できないためです。

マングリングアルゴリズムは、
それぞれのコンパイラによって違うため、
違うコンパイラが出力したオブジェクトファイルを利用する事はできません。

また、Cでコンパイルされたオブジェクトファイルは、
マングリングされていないので、
C++コンパイラからリンクする際は、
「extern "C"」 と宣言しマングリングしないようにする必要があります。

呼び出し規約

関数を呼び出す際の規約もあります。
引数をスタックにいれるとか、レジスタに入れるとかです。
これを一緒にしなければ、おかしくなります。
基本的な規約は下記の通りです。
 ・cdecl(Cでの規約で主にスタックを利用)
 ・thiscall(C++でのメンバ関数の規約)
 ・stdcall(Windows標準の関数規約でprintf等の可変引数は使えません。VB、C#もサポート)
 ・fastcall(高速な関数規約、BorlandC++Builderでは、主としてこれを使います。)
 ・clrcall(.NET Frameworkの専用規約)


・覚書
 ・スタック
 ・レジスタ
さらに情報が欲しい方は、Google検索で  
Google
・TOPへ戻る

メールはこちらに