ライブラリ

ライブラリとは



ライブラリとは、複数のプログラムを再利用可能な形でまとめたものです。ライブラリ単体ではプログラムとして実行できない場合が多く、他のプログラムに機能を提供するコードの集まりと考えることができます。ライブラリには、ソースコードの形式のものや、オブジェクトコード、または専用の形式で提供されるものがあります。UNIX環境では、オブジェクトコードをアーカイブツールでまとめて利用することが一般的です。

ライブラリは、プログラムの「書庫」のようなものであり、効率的にプログラムを開発するために不可欠です。そのため、ライブラリ内の関数やデータに素早くアクセスするための索引方法が重要となります。

APIとSDK



オペレーティング[[システム]](OS)などの実行環境に実装された機能を、アプリケーション[[ソフトウェア]]から利用できるように定義されたものがAPI(アプリケーションプログラミングインターフェース)です。APIは、一般的にソフトウェア開発キット(SDK)を通じて利用できるようになっています。広義では、APIとライブラリを同じものとみなすこともあります。

SDKには、プログラマーが低レベルのAPIやライブラリを直接扱うことなく、比較的簡単にアプリケーションを構築できるように、高レベルのアプリケーションフレームワークが含まれていることがあります。このようなソフトウェアフレームワークもライブラリの一種として捉えることができます。

ライブラリは、ソフトウェアだけでなく、音声データなど他の再利用可能なデータ集合体にも適用されることがあります。

動的リンク



動的リンクとは、ライブラリ内のコードやデータを実行ファイルのビルド時にコピーするのではなく、ディスク上の別のファイルとして保持する仕組みです。ビルド時にリンカが記録するのは、実行ファイルが必要とするライブラリの部分(関数名やインデックス)のみです。リンク作業の大部分は、アプリケーションがメモリにロードされた時、または実行時に行われます。

リンクを行うプログラムはローダーと呼ばれ、通常はOSの一部です。ローダーは、必要なライブラリをディスク上で探し、プロセスのメモリ空間にマッピングします。一部のOSでは、ライブラリはプロセスの実行開始前にリンクされる必要がありますが、多くのOSではライブラリが実際に参照されたときにリンクする「遅延読み込み」が可能です。

動的リンクライブラリは、Windows環境では「DLL」という略称で広く知られており、拡張子は通常「.dll」です。動的リンクライブラリの中でも、複数のプログラムで共有・再利用可能なものは、共有ライブラリと呼ばれます。例えば、Windows APIの大半はシステムDLLとして実装されており、あらゆるWindowsアプリケーションから利用できます。

動的リンクの仕組み



動的リンクでは、メモリ上のライブラリの位置がロードされるまで確定しないため、特別な処理が必要です。ディスク上のファイルに絶対アドレスを書き込むことはできないため、代わりに、コンパイル時にアドレス欄が空欄のシンボルテーブルが用意されます。ライブラリへの参照はすべてこのシンボルテーブルを経由し、メモリにロードされた時にローダーがテーブルを書き換えます。

ライブラリもまた、自身のメソッド(関数やサブルーチン)のテーブルを持っており、ライブラリに入るときは、このテーブルを経由して各ルーチンにジャンプします。これにより、ルーチンコールにわずかなオーバーヘッドが発生しますが、通常は無視できるほど小さいものです。

動的リンカ・ローダーの課題



動的リンカ・ローダーの機能は様々です。実行ファイルに格納された明示的なライブラリパスに依存する場合、ライブラリ名やディスク上の配置を変更するとシステムが作動しなくなることがあります。より一般的な手法としては、ライブラリ名だけを実行ファイルに格納し、OSがディスク上のライブラリを検索します。

Windowsでは、ライブラリの探索順序が定義されており、不正なDLLが探索の上位に置かれると、実行ファイルが不正動作する可能性があります。これは「DLL地獄」と呼ばれる問題として知られています。

Windows XP以降では、「Side-by-Sideアセンブリ」というメカニズムが導入され、ライブラリのファイル名ではなく、ライブラリの署名によってリンクすべきライブラリを決定することで、DLL地獄の問題を軽減しようとしています。しかし、システムライブラリをオーバーライドして独自機能を実装する際には、このメカニズムが逆に障害となることもあります。

動的リンクの歴史



動的リンクの起源は定かではありませんが、1960年代後半のMTSまで遡ることができます。

動的読み込み



動的読み込みとは、動的リンクの下位カテゴリであり、ビルド時にリンクされていないダイナミックリンクライブラリを、実行中のプログラムが明示的にロードする仕組みです。これは明示的リンクとも呼ばれます。

この場合、ライブラリはプラグインモジュールとして使用されるのが一般的で、表計算プログラムのアドインなどが典型的な例です。

動的読み込みのAPI



動的ライブラリをサポートするシステムは、モジュールの動的読み込みAPIもサポートしています。例えば、WindowsではLoadLibrary()とGetProcAddress()が用意されており、Unix系システムではdlopen()とdlsym()が用意されています。不要になったモジュールを解放(アンロード)するためのAPIも提供されています。

これらのAPIは、アプリケーション内でプラグインシステム実装する際に非常に役立ちます。例えば、ユーザーが機能拡張を可能にするプラグインシステムをアプリケーションに組み込むことができます。

.NET Frameworkと動的読み込み



.NET Frameworkでは、ライブラリのアセンブリは必要になったタイミングで動的かつ自動的にロードされる遅延読み込みが基本ですが、アセンブリの明示的なアンロードはできません。.NET 4以降では、プラグインシステム実装を容易にするManaged Extensibility Frameworkがサポートされています。

スクリプト言語と動的読み込み



スクリプト言語の処理系(インタプリタなど)をアプリケーションに組み込んで、定型処理の自動化や機能拡張のためにユーザーが記述したプログラムを実行できるようにしているものもあります。これは、外部のユーザーコードを広義の動的ライブラリとして活用するプラグイン機能と言えます。

リモートライブラリ



別のライブラリの形態として、完全に分離された実行ファイルを遠隔手続き呼び出し(RPC)で接続するものがあります。このアプローチでは、OSの再利用が最大限に活用されます。ライブラリサポートのコードは、アプリケーションサポートのコードやセキュリティサポートのコードと共通化できます。さらに、このライブラリはネットワーク経由で別のマシン上に存在することも可能です。

欠点としては、ライブラリコールのたびに無視できないオーバーヘッドが発生することです。しかし、このアプローチはクライアントサーバシステムアプリケーションサーバで一般的に利用されています。

共有ライブラリ



ライブラリは、動的か静的かという分類に加えて、プログラム間で共有される方式でも分類できます。動的ライブラリは共有をサポートしており、複数のプログラムが同時に同じライブラリを使用できます。一方、静的ライブラリは各プログラムにリンクされるため、共有することはできません。

共有ライブラリという用語は曖昧な場合がありますが、一般的にはディスク上のコードを複数のプログラムが共有すること、およびメモリ上のコードを複数のプロセスが共有することの両方を指します。特に後者の共有は、メモリの効率的な利用を促進します。

共有ライブラリの利点



メモリ上の共有ライブラリは、UNIXでは位置独立コード(PIC)を使って実現されます。これは柔軟なアーキテクチャですが複雑です。Windowsでは、DLLごとにマップするアドレスを事前に決めておくなどしてメモリ上で共有可能にしています。

最近のOSでは、共有ライブラリは通常の実行ファイルと同じ形式になっています。これにより、単一のローダーで両方をロードでき、シンボルテーブルさえあれば実行ファイルを共有ライブラリとして使うことができます。

マルチスレッドと共有ライブラリ



マルチスレッド環境下でライブラリを使用する場合、ライブラリ内のデータ領域がスレッド毎に用意されていないと、複数のスレッドが同じライブラリルーチンを同時に使用すると問題が発生する可能性があります。そのため、実行ファイル側で同時に複数のスレッドが同じライブラリルーチンを使用しないように注意する必要があります。

オブジェクトライブラリ



1990年代初頭には、オブジェクト指向プログラミング(OOP)が普及し始め、従来のライブラリに加えて、オブジェクト間の依存関係などの情報が必要になりました。これは、OOPの継承という機能の副作用であり、あるメソッドの定義が複数の場所に分散して配置される可能性があります。

また、多層構造のシステムの考え方も登場し、表示プログラムが汎用コンピュータ記憶装置や演算機能を利用するようになり、RPCが標準化される必要がありました。

オブジェクトライブラリの試み



主要な汎用機メーカーが協力して、どこでも使えるOOPライブラリ形式を開発しようとしました。このようなシステムはオブジェクトライブラリと呼ばれ、リモートアクセスが可能なものは分散オブジェクトと呼ばれました。例として、マイクロソフトのCOMやCORBAベースのシステムなどがあります。

一時期、オブジェクトライブラリは「次の大きな出来事」とされましたが、最終的にはマイクロソフトのCOMとNeXTのPDO以外は、あまり使われなくなりました。

Javaとオブジェクトライブラリ



Javaでは、オブジェクトライブラリとして主にJARが使われています。JARファイルには、クラスのバイトコードが格納されており、Java仮想マシンや特殊なクラスローダーがロードします。Java Native Interface(JNI)を使うことで、C/C++などのネイティブコードで記述された関数をJavaメソッドとして呼び出すことができますが、対応するライブラリモジュールを明示的にロードする必要があります。

ライブラリの命名規則



GNU/Linux、Solaris、BSDの派生OS



ライブラリのファイル名は、接頭辞「lib」で始まり、拡張子として「.a」(静的ライブラリ)または「.so」(ダイナミックリンクライブラリ)が使用されます。インタフェース番号が多重拡張子として付与されることがあります。

macOS



macOSでは、動的ライブラリの拡張子に「.dylib」が使われますが、「.so」も使用できます。多くの動的ライブラリは「バンドル」という特別な場所に置かれ、関連ファイルやメタデータもそこに格納されます。

Microsoft Windows



Windowsでは、ライブラリのファイル名に対する厳格な命名規則はありませんが、いくつかの拡張子が用意されています。「.lib」という拡張子のファイルは、静的ライブラリまたはDLLのインポートライブラリとして使用されます。ダイナミックリンクライブラリには通常「.dll」という拡張子が付けられます。

まとめ



この記事では、ライブラリの基本的な概念から、動的リンク、動的読み込み、リモートライブラリ、共有ライブラリ、オブジェクトライブラリ、そして命名規則まで幅広く解説しました。ライブラリは、ソフトウェア開発において、コードの再利用性、効率性、拡張性を高めるために不可欠な要素です。これらの知識は、より高度なプログラミングスキルを習得するための基礎となるでしょう。

もう一度検索

【記事の利用について】

タイトルと記事文章は、記事のあるページにリンクを張っていただければ、無料で利用できます。
※画像は、利用できませんのでご注意ください。

【リンクついて】

リンクフリーです。