落穂拾い

スタティックリンク(静的リンク)とダイナミックリンク(動的リンク)

実は、リンカが行うリンク処理には2種類あり、スタティックリンクとダイ ナミックリンクと呼ばれている。

スタティックリンクとは

スタティックリンクでは、コンパイル後のリンク処理の際に、 実際にライブラリの中のルーチンを実行可能プログラム (executable) に含めてしまう。 その分、プログラムのサイズは大きくなる。

ダイナミックリンクとは

ダイナミックリンクでは、実際にライブラリ内のルーチンが結合されるのは、 プログラムの実行時である。 この結合はメモリ空間上で起こるので、 ディスクに格納されているプログラムには何の変更もされない。

コンパイル後のリンク処理の際には、 実行時に結合ができるようにするための設定をファイルに書き込むだけである。 (もちろん、ライブラリ以外のファイルについては本当に結合してしまう。) このようにすれば、バイナリにライブラリルーチンが含まれないので、 プログラムが小さくなる。

ダイナミックリンクとスタティックリンクの実行例:

% cat hello.c        単に "Hello, world!"と印刷するだけのプログラム
#include <stdio.h>

int main()
{
  printf("Hello, world!\n");
  return 0;
}
% cc -o hello.dynamic hello.c        ←普通に cc でコンパイルするとダイナミックリンクが行われる
% ls -l hello.dynamic
-rwxr-xr-x    1 kbys     teach        4631 Jan 17 13:45 hello.dynamic*        ←ダイナミックリンクの場合、実行可能プログラムのサイズは小さい
% cc -static -o hello.static hello.c        ← -static オプションを指定するとスタティックリンクが行われる
% ls -l hello.static
-rwxr-xr-x    1 kbys     teach      404251 Jan 17 13:45 hello.static*        ←スタティックリンクの場合、実行可能プログラムのサイズは大きい

ダイナミックリンクの利点

例えば、printf 関数は多くのプログラムで使われるが、 それらすべてのプログラムがスタティックリンクされているとすると、 全く同じ printf というルーチンが多くのプログラムに重複して含まれていることになり、 記憶領域が無駄に使われていることになる。 ダイナミックリンクであれば、このような無駄がない。 ダイナミックリンク方式では、 ライブラリ関数はライブラリファイルの中だけに置いて、 多くのプログラムでそれを共有して使っている格好になるので、 ダイナミックリンク用に作られているライブラリは共有ライブラリ (shared library) と呼ばれる。

もう一つの利点として、 ライブラリの置き換えが容易にできることがあげられる。 例えば、あるライブラリにバグがあることがわかり、 新しいバージョンに置き換えなければならないとする。 スタティックリンクされたプログラムの場合、 ライブラリが置き換えられたあと、再コンパイルしなければならないが、 ダイナミックリンクされている場合は、 実行時に自動的に新しいバージョンのライブラリが読み込まれるので、 再コンパイルの必要がない。

UNIX の場合、実行時に標準のディレクトリ以外の場所にあるライブラリを 読み込ませるように設定することもできる。例えば、どうしても古いライブラ リでなければ動かないソフトがあった時、そのソフトの実行時だけ古いライブ ラリの置かれた場所からライブラリを読み込ませることが可能である。あるい は、標準のライブラリと互換性のないライブラリが必要な時にそれが置かれた ディレクトリから読み込ませることもできる。このように、ライブラリの扱い に柔軟性を持たせられるのもダイナミックリンクの利点である。

ダイナミックリンクの問題点

一方、ダイナミックリンクされたプログラムは、必要な共有ライブラリのな いコンピュータに持って行くと動作しない。また、共有ライブラリが使えない ような特殊な状況にある時も使えない。例えば、トラブルが起きて共有ライブ ラリの入っているディスク(あるいはディスクの区画(パーティション))が使え ない時、ディスクのバックアップのために、共有ライブラリの入っているディ スクをアンマウントしている時などである。(バックアップはできればアンマ ウントした状態で取るほうがよいし、バックアップのやり方によっては、マウ ントされているとバックアップできない。) そういう状況のために、スタティッ クリンクされたエディタを用意しているという人もいる。(そういうエディタ を使って色々な設定ファイルを書き換えてトラブルを解決しようというわけで ある。)

しかし、このような特殊な状況以外では、 一般にスタティックリンクよりもダイナミックリンクのほうが有利である。 そのため、今日(少なくとも UNIX では)ほとんどのプログラムは ダイナミックリンクされている。

Windows にもダイナミックリンクの仕組みはあり、共有ライブラリに相当す るものはダイナミックリンクライブラリと呼ばれている。ダイナミックリンク ライブラリの拡張子は .dll になっている。

あるソフトウェア A を Windows にインストールしたとたんに、他のソフト ウェア B が使えなくなった、という話はよく聞く。原因としてよくあるのが、 A のインストール時に既存の dll ファイルを書き換える形で新しい dll ファ イルがインストールされてしまい、既存のものを利用していたソフトウェア B が動かなくなってしまう、というケースである。

Windows のインターネットエクスプローラ (IE) のセキュリティホールが年がら年中報告されているのはご存知の通り。 危険だというので IE の使用をやめている人もよくいるが、 実はそれだけでは安心できない。 IE のために作られたダイナミックリンクライブラリを他のソフトウェアも使っていることがあるからだ。 ライブラリにセキュリティホールがあれば、 それを使っているすべてのソフトウェアに影響がある。