#
4.2 Unix と Windows の相違点

Unix と Windows では、コードの実行時読み込みに全く異なる パラダイムを用いています。動的ロードされるようなモジュールをビルド しようとする前に、自分のシステムがどのように動作するか 知っておいてください。

Unixでは、共有オブジェクト (.so) ファイルにプログラムが 使うコード、そしてプログラム内で使う関数名やデータが入っています。 ファイルがプログラムに結合されると、これらの関数やデータに 対するファイルのコード内の全ての参照は、メモリ内で関数やデータが 配置されている、プログラム中の実際の場所を指すように変更されます。 これは基本的にはリンク操作にあたります。

Windows では、動的リンクライブラリ (.dll) ファイルには ぶら下がり参照 (dangling reference) はありません。 その代わり、関数やデータへのアクセスはルックアップテーブルを 介します。従って DLL コードの場合、実行時にポインタがプログラム メモリ上の正しい場所を指すように修正する必要はありません; その代わり、コードは常に DLL のルックアップテーブルを使い、 ルックアップテーブル自体は実行時に実際の関数やデータを指すように 修正されます。

Unixには、唯一のライブラリファイル形式 (.a) しかありません。 .a ファイルには複数のオブジェクトファイル (.o) 由来の コードが入っています。共有オブジェクトファイル (.so) を作成 するリンク処理の段階中に、リンカは定義場所の不明な識別子に遭遇する ことがあります。このときリンカはライブラリ内のオブジェクトファイルを 検索します; もし識別子が見つかると、リンカはそのオブジェクトファイルから 全てのコードを取り込みます。

Windows では、二つの形式のライブラリ、静的ライブラリとインポート ライブラリがあります (どちらも.lib と呼ばれています)。 静的ライブラリは Unix における .a ファイルに似ています; このファイルには、必要に応じて取り込まれるようなコードが入っています。 インポートライブラリは、基本的には特定の識別子が不正ではなく、 DLL がロードされた時点で存在することを保証するためにだけ使われます。 リンカはインポートライブラリからの情報を使ってルックアップテーブル を作成し、DLL に入っていない識別子を使えるようにします。 アプリケーションや DLL がリンクされるさい、インポートライブラリ が生成されることがあります。このライブラリは、アプリケーションや DLL 内のシンボルに依存するような、将来作成される全ての DLL で 使うために必要になります。

二つの動的ロードモジュール、B と C を作成し、別のコードブロック A を 共有するとします。Unixでは、 A.a を B.so やC.so をビルドするときのリンカに渡したりはしません; そんなことをすれば、 コードは二度取り込まれ、B と C のそれぞれが自分用のコピーを持って しまいます。 Windows では、A.dll をビルドするとA.lib もビルドされます。 B や C のリンクにはA.lib を渡します。 A.lib にはコードは 入っていません; 単に A のコードにアクセスするするために実行時に 用いられる情報が入っているだけです。

Windows ではインポートライブラリの使用は "`import spam`"とするようなものです; この操作によって spam の名前にアクセスできますが、 コードのコピーを個別に作成したりはしません。Unixでは、ライブラリとの リンクはむしろ "`from spam import *`" に似ています; この操作では個別にコードのコピーを生成します。