モジュール定義ファイル
ILINK32 では、モジュール定義ファイルを使用できます。モジュール定義ファイルは、Windows アプリケーションの内容やシステム要件に関する情報を ILINK32 に伝えるための ASCII テキスト ファイルです。モジュール定義ファイルの作成には、IMPDEF を使用します。
モジュール定義ファイルの役目は、生成する .EXE または .DLL の命名、アプリケーション タイプの特定、インポート/エクスポートする関数の列挙、コード セクション属性やデータ セグメント属性の記述、付加的なコード セクションやデータ セグメントの属性の指定、スタック サイズの指定、スタブ プログラムの組み込みの指定などです。
目次
CODE 文
コード セクションのデフォルト属性を定義します。コード セクションには任意の名前を付けることができますが、名前の終わりに CODE の付くセクション クラス(たとえば CODE や MYCODE など)に属している必要があります。
CODE [PRELOAD | LOADONCALL] [EXECUTEONLY | EXECUTEREAD]
- PRELOAD: コードは、呼び出し元プログラムが読み込まれるときに読み込まれます。
- LOADONCALL(デフォルト): コードは、プログラムから呼び出されたときに読み込まれます。
- EXECUTEONLY: コード セクションは実行のみ可能です。
- EXECUTEREAD(デフォルト): コード セクションは読み取りおよび実行可能です。
- FIXED(デフォルト): セクションは固定のメモリ位置にそのまま残ります。
- MOVEABLE: セクションは移動可能です。
- DISCARDABLE: セクションは不要になったら破棄可能です(必然的に MOVEABLE になります)。
- NONDISCARDABLE(デフォルト): セクションは破棄不能です。
DATA 文
データ セグメントの属性(以下のいずれか)を定義します。
DATA [NONE | SINGLE | MULTIPLE] [READONLY | READWRITE] [PRELOAD | LOADONCALL] [SHARED | NONSHARED]
- NONE: データ セクションは作成されません。このオプションは、ライブラリの場合のみ使用可能です。
- SINGLE(.DLL の場合のデフォルト): データ セクションは 1 つだけ作成され、すべてのプロセスで共有されます。
- MULTIPLE(.EXE の場合のデフォルト): データ セクションはプロセスごとに作成されます。
- READONLY: データ セクションは読み取り専用です。
- READWRITE(デフォルト): データ セクションは読み取りおよび書き込み可能です。
- PRELOAD: データ セクションは、それを使用するモジュールが初めて読み込まれるときに読み込まれます。
- LOADONCALL(デフォルト): データ セクションは初回アクセス時に読み込まれます (32 ビット アプリケーションの場合、LOADONCALL は無視されます)。
- SHARED: データ セクションの 1 つのコピーがすべてのプロセスで共有されます。
- NONSHARED(.DLL の場合のデフォルト): データ セクションを使用する必要のあるプロセスごとに、そのデータ セクションのコピーが読み込まれます。
DESCRIPTION 文(省略可能)
アプリケーション モジュール内にテキストを挿入します。通常は、作成者、日時、著作権などの情報を埋め込むのに使用されます。
DESCRIPTION 'Text'
テキストは、一重引用符(')で囲まれた ASCII 文字列です。
EXETYPE 文
アプリケーションのデフォルトの実行可能ファイル(.EXE)ヘッダー タイプを定義します。下位互換性を保つために 32 ビット アプリケーションの場合もこのセクションをそのまま残すことができますが、EXETYPE を変更する必要がある場合は、「NAME 文」を参照してください。
EXETYPE [WINDOWAPI] | [WINDOWCOMPAT]
- WINDOWAPI: Windows 実行可能ファイルであることを指定します(ILINK32 の
-aa
オプションと同等です)。 - WINDOWCOMPAT: Windows 互換のキャラクタモード実行可能ファイルであることを指定します(ILINK32 の
-ap
オプションと同等です)。
EXPORTS 文
エクスポートする関数の名前と属性を定義します。EXPORTS キーワードは、そこから定義が始まることを示します。その後に、1 行に 1 つずつ任意個のエクスポート定義を記述することができます。
EXPORTS <ExportName> [<Ordinal>] [RESIDENTNAME] [<Parameter>]
- <エクスポート名>: エクスポートするシンボルを定義する ASCII 文字列を次のように指定します。
<EntryName> [=<InternalName>]
- <EntryName> は実行可能ファイルのエントリ テーブルに記載される名前で、外部から参照できます。
- <InternalName> は、アプリケーション内部でこのエントリを参照するのに使用する名前です。
- <ordinal> は、関数の順序値を次のように定義します。
@<ordinal>
- ここでの
<ordinal>
は、関数の順序値を指定する整数値です。DLL からエクスポートされた関数をアプリケーション モジュールまたは DLL モジュールから呼び出すとき、呼び出し元のモジュールでは、その関数を名前または順序値で参照することができます。序数で関数を参照する場合は、関数の特定に文字列の比較が不要なため、より高速です。使用するメモリを少なくするには、関数のエクスポートを(その関数の DLL 側から)序数で行い、関数のインポート/呼び出しを(呼び出しモジュール側から)序数で行います。 - 関数を序数でエクスポートすると、その名前は非常駐名前テーブルに登録されます。関数を名前でエクスポートすると、その名前は常駐名前テーブルに登録されます。モジュールの常駐名前テーブルは、そのモジュールが読み込まれるたびにメモリ内に存在しますが、非常駐名前テーブルはそうではありません。
- RESIDENTNAME: 関数の名前が常に常駐でなければならないことを指定します。これが役に立つのは、序数でエクスポートする場合のみです(この場合には名前がデフォルトでは常駐にならないからです)。
- <Parameter> は省略可能な整数値で、関数にパラメータとして渡されることになっている単語の数を指定します。
HEAPSIZE 文
アプリケーションのローカル ヒープに必要なバイト数を定義します。アプリケーションでは、ローカル メモリを割り当てるたびに、このローカル ヒープを使用します。
HEAPSIZE <Reserve>[, <Commit>]
- <Reserve> は 10 進値または 16 進値で、デフォルトは 1 MB です。.DEF ファイルで 64 KB 未満の予約値が指定された場合、32 ビット ポートの下位(16 ビット)互換性を確保しやすくするために、リンカでは 1 MB のデフォルト値を使用します。
- <Commit> は 10 進値または 16 進値です。コミット サイズは省略可能で、指定しない場合は、デフォルトで 4 KB になります。指定可能なコミット サイズの最小値は 0 です。さらに、指定またはデフォルトのコミット サイズは常に予約サイズ以下でなければなりません。
メモリの予約サイズとは、物理メモリとページング ファイルのどちらかに割り当て可能なメモリ量の最大値のことです。つまり、予約サイズは確保し得る最大のヒープ サイズを指定します。指定したメモリ量の予約と必要時の割り当ては、オペレーティング システムによって保証されます。
コミットされたメモリの意味は、オペレーティング システムによって異なります。Windows NT では、コミットされたメモリとは、アプリケーションの読み込み/初期化時にヒープ用に割り当てられる物理メモリの量のことです。コミットされたメモリを指定すると、物理メモリとページング ファイルのどちらかに領域が割り当てられます。コミット サイズの値が大きいほど、アプリケーションでさらにヒープ領域が必要になったときに時間の節約になりますが、その反面、メモリ要件が厳しくなり、見込まれる起動時間も長くなります。{{f|cmd|
ヒープ領域の予約サイズまたはコミット サイズが .DEF ファイルでどのように指定されていても、ILINK32 のコマンドライン オプション -H
または -Hc
を使って、それらをオーバーライドすることができます。-H
を指定すると、.DEF ファイルで指定可能な最小値 64 KB よりも小さいヒープ予約サイズを指定することができます。
IMPORTS 文
DLL からインポートする関数の名前と属性を定義します。IMPORTS キーワードでそこから定義が始まることを示し、その後に、1 行に 1 つずつ任意個のインポート定義を記述します。
IMPORTS [<InternalName>=]<ModuleName>.<Entry>
- <InternalName> は、アプリケーションが関数を呼び出すときに使用する一意の名前を指定する ASCII 文字列です。
- <ModuleName> は、関数が含まれている実行可能モジュールの名前を定義する 1 つ以上の ASCII 大文字を指定します。このモジュール名は実行可能ファイルの名前に一致する必要があります。たとえば、ファイル SAMPLE.DLL のモジュール名は SAMPLE です。
- <Entry> は、インポートする関数を指定します。関数の名前を表す ASCII 文字列か、関数の順序値を表す整数のどちらかです。
インポートする DLL 関数を IMPORTS 文に列挙する代わりに、DLL のインポート ライブラリを ILINK32 コマンドラインで指定したり RAD Studio の[プロジェクト マネージャ]で組み込むこともできます。インポートする DLL 関数を IMPORTS 文に列挙する代わりに、DLL のインポート ライブラリを[プロジェクト マネージャ]で組み込むことができます。
インポートする関数、クラス、あるいはデータを宣言するには、__declspec(dllimport)
と __import
のどちらかを使用する必要があります。__declspec(dllimport)
の使用をお勧めします。
次のようにすると、IMPORTS キーワードを(グローバル)変数にも適用することができます。
[ in the dll source file (dll.cpp) ] int sample = 100;
[ dll.def ] EXPORTS _sample
[ in application source file (app.cpp) ] int _declspec(dllimport) sample;
[ app.def ] IMPORTS dll._sample
LIBRARY 文
DLL モジュールの名前を定義します。モジュール定義ファイルには、LIBRARY 文で .DLL を指定することも、NAME 文で .EXE を指定することもできます。ライブラリのモジュール名は実行可能ファイルの名前に一致する必要があります。たとえば、ライブラリ MYLIB.DLL のモジュール名は MYLIB です。
LIBRARY <LibrarName> [INITGLOBAL | INITINSTANCE]
- <LibraryName>(省略可能)は、ライブラリ モジュールの名前を定義する ASCII 文字列です。
LibraryName
を指定しない場合、ILINK32 では、ファイル名から拡張子を取り除いたもので代用します。モジュール定義ファイルに NAME 文も LIBRARY 文も含まれていない場合、ILINK32 は、ModuleName
パラメータのない NAME 文であるとみなします。 - INITGLOBAL: ライブラリ初期化ルーチンが呼び出されます。
- INITINSTANCE: ライブラリが新しいプロセスで使用されるたびに、ライブラリ初期化ルーチンが呼び出されます。
NAME 文
アプリケーションの実行可能モジュールの名前を定義します。関数をエクスポートする際に、モジュール名でモジュールが識別されます。NAME 文は EXETYPE 文よりも前に記述する必要があります。NAME 文と EXETYPE 文で同じターゲット タイプを指定していない場合、リンカは NAME 文で記載されたタイプを使用します。
NAME <ModuleName> [WINDOWSAPI] | [WINDOWCOMPAT]
- <ModuleName>(省略可能): 実行可能モジュールの名前を定義する 1 つ以上の大文字 ASCII 文字を指定します。この名前は実行可能ファイルの名前に一致する必要があります。たとえば、実行可能ファイルが SAMPLE.EXE であるアプリケーションのモジュール名は SAMPLE です。
ModuleName
が指定されていない場合、ILINK32 は、モジュール名が実行可能ファイルのファイル名に一致するものとみなします。たとえば、モジュール名が未指定で、実行可能ファイルの名前が MYAPP.EXE である場合、ILINK32 は、モジュール名が MYAPP であるとみなします。モジュール定義ファイルに NAME 文も LIBRARY 文も含まれていない場合、ILINK32 は、<ModuleName>
パラメータのない NAME 文であるとみなします。
- WINDOWSAPI: Windows 実行可能ファイルであることを指定します(ILINK32 の
-aa
オプションと同等です)。 - WINDOWCOMPAT: Windows 互換のキャラクタモード実行可能ファイルであることを指定します(ILINK32 の
-ap
オプションと同等です)。
SECTIONS 文
イメージ ファイルに含まれる 1 つ以上のセクションの属性を設定できます。このステートメントを使用して、異なるタイプのセクションごとにデフォルト属性をオーバーライドすることができます。
SECTIONS<section_name> [CLASS '<ClassName>'] <attributes>
- SECTIONS: ここからセクション定義リストが始まることを示します。
- SECTIONS キーワードの後は、セクション定義ごとに別々の行に記載されている必要があります。なお、SECTIONS キーワードは最初のセクション定義と同じ行に書かれていても、その前の行に書かれていてもかまいません。さらに、.DEF ファイルには SECTIONS 文を 1 つまたは複数記述することができます。SEGMENTS キーワードは SECTIONS のシノニム(同義語)としてサポートされています。
- <ClassName>: 大文字と小文字が区別されます。互換性を保つために CLASS キーワードがサポートされていますが、それは無視されます。
- <Attributes>: EXECUTE、READ、SHARED、WRITE の中から 1 つ以上選択して指定します。
SEGMENTS 文
付加的なコード セクションやデータ セクションの属性を定義します。SEGMENTS キーワードは SECTIONS のシノニム(同義語)としてサポートされています。構文は次のとおりです。
SEGMENTS <SegmentName> [CLASS '<ClassName>'] [<MinAlloc>] [SHARED | NONSHARED] [PRELOAD | LOADONCALL]
<SegmentName>
: 新しいセグメントの名前を表す文字列です。標準セグメント名 _TEXT や _DATA(それぞれ標準コード セグメントと標準データ セグメントを表します)を含め、どのような名前でもかまいません。<ClassName>
(省略可能): 指定されたセグメントのクラス名です。クラス名が指定されない場合、ILINK32 では CODE というクラス名を使用します。<MinAlloc>
(省略可能): セグメントの最小割り当てサイズを指定する整数です。ILINK32 ではこの値は無視されます。- SHARED: セグメントの 1 つのコピーがすべてのプロセスで共有されます。
- NONSHARED(.EXE と .DLL の場合のデフォルト): セグメントを使用する必要のあるプロセスごとに、そのセグメントのコピーが読み込まれます。
- PRELOAD: セグメントは直ちに読み込まれます。
- LOADONCALL: セグメントはアクセス時または呼び出し時に読み込まれます(ILINK32 ではこれは無視されます)。リソース コンパイラで LOADONCALL オプションを無効にして、セグメントを事前にロードすることができます。
STACKSIZE 文
アプリケーションのローカル スタックに必要なバイト数を定義します。アプリケーションでは、関数呼び出しを行うたびに、このローカル スタックを使用します。
STACKSIZE <Reserve>[, <Commit>]
<Reserve>
は 10 進値または 16 進値で、デフォルトは 1 MB です。.DEF ファイルで 64 KB 未満の予約値が指定された場合、下位(16 ビット)互換性を確保しやすくするために、リンカでは 1 MB のデフォルト値を使用します。<Commit>
は 10 進値または 16 進値です。コミット サイズは省略可能で、指定しない場合は、デフォルトで 8 KB になります。指定可能なコミット サイズの最小値は 4 KB です。さらに、指定またはデフォルトのコミット サイズは常に予約サイズ以下でなければなりません。
メモリの予約サイズとは、物理メモリとページング ファイルのどちらかに割り当て可能なメモリ量の最大値のことです。つまり、予約サイズは確保し得る最大のスタック サイズを指定します。
指定したメモリ量の予約と必要時の割り当ては、オペレーティング システムによって保証されます。
コミットされたメモリの意味は、オペレーティング システムによって異なります。Windows NT では、コミットされたメモリとは、アプリケーションの読み込み/初期化時にスタック用に割り当てられる物理メモリの量のことです。コミットされたメモリを指定すると、物理メモリとページング ファイルのどちらかに領域が割り当てられます。コミット サイズの値が大きいほど、アプリケーションでさらにスタック領域が必要になったときに時間の節約になりますが、その反面、メモリ要件が厳しくなり、見込まれる起動時間も長くなります。{{f|cmd|
スタック領域の予約サイズまたはコミット サイズが .DEF ファイルでどのように指定されていても、ILINK32 のコマンドライン オプション -S
または -Sc
を使って、それらをオーバーライドすることができます。-S
を指定すると、.DEF ファイルで指定可能な最小値 64 KB よりも小さいスタック予約サイズを指定することができます。
メモ: .DLL をコンパイルする際には、STACKSIZE 文を使用しないでください。
STUB 文
<FileName>
で指定された DOS 実行可能ファイルを、モジュールの先頭に付け加えます。ユーザーが不適切な環境で(たとえば、DOS で Windows アプリケーションを実行する場合など)この実行可能スタブを実行しようとすると、スタブから警告メッセージが表示され、実行が終了します。
STUB '<FileName>'
<FileName>
: モジュールに付加される DOS 実行可能ファイルの名前です。この名前は DOS ファイル名形式でなければなりません。<ファイル名> で指定されたファイルが現在のディレクトリにない場合、ILINK32 は、PATH 環境変数で指定されたディレクトリでそのファイルを探します。
C++Builder では、別のスタブが STUB 文で指定されていない限り、組み込みスタブを Windows アプリケーションの先頭に付け加えます。WINSTUB.EXE の組み込みはリンカで自動的に行われるため、STUB 文を使用してそれを行わないでください。
SUBSYSTEM 文
リンクするアプリケーションの Windows サブシステムとサブシステム バージョン番号を指定することができます。
SUBSYSTEM [<subsystem>,]<subsystemID>
<Subsystem>
(省略可能)の有効な値は次のいずれかです:WINDOWS、WINDOWAPI、WINDOWCOMPAT。<Subsystem>
を指定しない場合、リンカはデフォルトで WINDOWS サブシステムであるとみなします。<SubsystemID>
: "d.d"(d は 10 進数)の形式に従う必要があります。たとえば、Windows 4.0 を指定する場合は、次の 2 とおりの SUBSYSTEM 文のどちらかを使用することができます。
SUBSYSTEM 4.0
SUBSYSTEM WINDOWS 4.0
.DEF ファイルで指定されている SUBSYSTEM 文はすべて、ILINK32 のコマンドライン オプション -a
および -V
を使ってオーバーライドすることができます。