|
本サイトは移転しました。旧アドレスからのリダイレクトは2025年03月31日(月)まで有効です。
|
🛈 | ✖ |
ダイナミックリンクライブラリ(DLL)はソフトウェアバイナリ形態の一種で動的リンクを使ったライブラリのこと。
ウィンドウズのダイナミックリンクライブラリは実行時に動的リンクされるライブラリであり、実行ファイル作成時に静的リンクされるスタティックリンクライブラリと区別される。以下にDLLのインターフェースを示す。
以降は主にエクスポート関数を対象として説明する。
ランタイムライブラリを含む多くのライブラリがDLLとスタティックリンクライブラリを用意し、実行ファイルのリンク時にどちらかを選択する。C++でこのDLLを使用するにはインポートライブラリと呼ばれる仲介のスタティックリンクライブラリをリンクする。このように生成された実行ファイルはロード時にDLLをロードする(ロード時動的リンク)。DLL利用には実行時動的リンクという方法もあるが、後述のようにソースコードレベルで異なる。
本サイトがコンパイラとして使用するmingw-w64(正確にはmingw-w64が子プロセスとして起動するGNUリンカ)はデフォルトでランタイムのDLLインポートライブラリをリンクするが、オプション-staticを用いればスタティックリンクライブラリをリンクする。以下は標準C++ライブラリを供給するランタイムライブラリを例としたMSYS2のmingw64サブシステムにおける説明で、mingw-w64バージョン8.2.1の場合を示してパス名一部にバージョン表記を含む。
ライブラリ | ファイル名 | MSYS2パス |
---|---|---|
ダイナミックリンクライブラリ | libstdc++-6.dll | /mingw64/bin/libstdc++-6.dll |
DLLインポートライブラリ | libstdc++.dll.a | /mingw64/lib/gcc/x86_64-w64-mingw32/8.2.1/libstdc++.dll.a |
スタティックリンクライブラリ | libstdc++.a | /mingw64/lib/gcc/x86_64-w64-mingw32/8.2.1/libstdc++.a |
以下はMSYS2のpacmanで追加したライブラリ例として、wxWidgetsバージョン3.0.4のwxBaseライブラリを示す。ランタイムと異なりデフォルトでリンクされないため、リンク時にDLLインポートライブラリあるいはスタティックリンクライブラリを-lオプションで明示する。MSYS2はリンクされるファイルを標準ライブラリディレクトリに置くので、-Lオプションでのライブラリディレクトリの追加は不要となる。
ライブラリ | ファイル名 | MSYS2パス |
---|---|---|
ダイナミックリンクライブラリ | wxbase30u_gcc_custom.dll | /mingw64/bin/wxbase30u_gcc_custom.dll |
DLLインポートライブラリ | libwx_baseu-3.0.dll.a | /mingw64/lib/libwx_baseu-3.0.dll.a |
スタティックリンクライブラリ | libwx_baseu-3.0.a | /mingw64/lib/libwx_baseu-3.0.a |
DLLをロード時動的リンクする実行ファイルは対応するDLLがその探索パスに存在する必要がある。POSIXサブシステム環境ではコマンドサーチパス(環境変数PATH)にディレクトリ(上記例では/mingw64/bin)設定されているが、ウィンドウズ環境ではPATHに加えるか実行ファイルと同一ディレクトリにコピーを置く必要がある。
ウィンドウズのシステムコール(ウィンドウズAPI)はオペレーティングシステム中核(カーネル)を直接コールするユニックスライクと異なり、DLLエクスポート関数の形で与えられる。APIを供給するDLLをシステムDLLと呼ぶことがある。多数あるシステムDLLのうち主な三つを例示する。
DLL | 機能 | API関数の例 |
---|---|---|
kernel.dll | メモリ、入出力、プロセス・スレッド、同期 | WriteFile, GetProcessHeap, LoadLibrary |
gdi32.dll | グラフィックデバイスインターフェース | CreateFont, BitBlt, ChagneDisplaySettings |
user32.dll | ユーザーインターフェース | MessageBox, PostMessage, GetCursorPos |
msvcrt.dllはVisual C++(マイクロソフトのC++コンパイラ)のランタイムライブラリの一つでC言語標準ライブラリを供給する。他の多くのランタイムライブラリと共に95(OSR2)以降のウィンドウズに標準添付されているためシステムDLLと見なすこともできよう。mingw-w64のランタイムライブラリは動的リンクおよび静的リンク共にこのDLLを利用するため、厳密にはmingw-w64はランタイムライブラリを完全に静的リンクできない。
MSYS2は/usr/binディレクトリにmsys-2.0.dllを置きPOSIX互換システムとウィンドウズを仲介させる。MSYS2のmsys-2.0.dllは(仮想的な)オペレーティングシステムを実現するシステムDLLと言える。
mingw-w64はインポートライブラリの代わりにDLLを直接指定することで、ロード時動的リンクする実行ファイルを作成できる。これは正確にはコンパイラが子プロセスとして起動するGNUリンカのWIN32(cygwin/mingw)拡張機能である。
実行時動的リンクはDLLを実行ファイルロード時ではなく特定のAPI関数(LoadLibrary)実行時にロードする。他方、ロード時動的リンクと静的リンクはソースコードのコンパイルまで同じで、前者DLLインポートライブラリ(直接リンクなら前者DLL自身)あるいは後者スタティックリンクライブラリのどちらかをリンカで選択する。すなわちDLL実行時動的リンクはソースコードレベルから他と異なり、リンカによるリンクは関係ない。
本サイト | マイクロソフト(英語) | マイクロソフト(日本語) | 恐らく誤用 |
---|---|---|---|
ロード時動的リンク | Load-time dynamic linking | Load-time動的リンク | 動的リンク、静的ロード |
実行時動的リンク | Run-time dynamic linking | 実行時動的リンク | 動的ロード、動的読み込み |
実行ファイルは概ね以下の順番でロードするDLLを探索する。
マイクロソフトのドキュメントはこれをもう少し複雑に定義するが、本サイトはこれで十分とする。32ビット/64ビットのシステムDLLを共存させるリダイレクションや明確にDLLを指定するサイドバイサイドがあるが、POSIXサブシステムは用いておらず本サイトも利用しない。
公式に記述するドキュメントは恐らく存在しないが、実行ファイルはDLL探索においてアーキテクチャの異なるDLLをスキップする。例えば64ビット実行ファイルはDLL探索で32ビットDLLを発見してもロードせず、ディレクトリ探索を続行し64ビットDLLを発見すればそちらをロードする。ただし32ビットDLL発見後に64ビットDLLを発見できなかった場合は32ビットDLLをロードしたものとしてエラーを報告する。
本サイトは32ビット/64ビットアプリケーションを統合開発環境で開発するため、PATH設定は十分な検討を必要とする。アーキテクチャの異なるDLLをスキップする機能は積極的に利用するが、非ドキュメンテッドの可能性が高く懸念が残る。