$WEAKPACKAGEUNIT 指令の使用

提供: RAD Studio
移動先: 案内検索

パッケージのコンパイル への移動


Delphi の場合:

$WEAKPACKAGEUNIT 指令は、パッケージの .dcp ファイルおよび .bpl ファイルへの .dcu ファイルの格納方法に影響を及します (コンパイラで生成されるファイルについては、「パッケージと標準 DLL」を参照)。{$WEAKPACKAGEUNIT ON} がユニット ファイルで検出された場合、コンパイラはそのユニットを bpl からできるだけ除外し、別のアプリケーションやパッケージで必要になったときには、そのユニットのパッケージ化されていないローカル コピーを作成します。この指令を付けてコンパイルされたユニットは、弱くパッケージ化されていると言われます。

たとえば、ユニットが 1 つだけ(unit1)含まれている pack1 というパッケージを作成したとしましょう。unit1 ではもう他のユニットを使用することはなく、rare.dll を呼び出すと想定します。パッケージをコンパイルする際に、unit1.pas(Delphi の場合)または unit1.cpp(C++ の場合)に {$WEAKPACKAGEUNIT ON} 指令が記述されていると、unit1 は pack1.bpl には含まれません。このため、rare.dll のコピーを pack1 と一緒に配布しなくてもよくなります。ただし、pack1.dcp には依然として unit1 が含まれています。pack1 を使用する別のパッケージやアプリケーションから unit1 が参照されている場合は、それが pack1.dcp からコピーされ、プロジェクトに直接コンパイルされます。

ここで、2 つ目のユニット unit2 を pack1 に追加するとしましょう。unit2 は unit1 を使用するとします。今度は、pack1 のコンパイル時に unit1.pas に {$WEAKPACKAGEUNIT ON} を指定したとしても、コンパイル後、unit1 は pack1.bpl に含まれます。しかし、unit1 を参照している他のパッケージやアプリケーションでは、(パッケージ化されていない)コピーを pack1.dcp から取得して使用します。

メモ: {$WEAKPACKAGEUNIT ON} 指令が含まれているユニット ファイルには、グローバル変数、initialization セクション、finalization セクションが存在してはいけません。

{$WEAKPACKAGEUNIT ON} 指令は、他のプログラマにパッケージを配布する開発者向けの高度な機能です。この機能は、使用頻度の低い DLL の配布を避け、また、同じ外部ライブラリに依存する可能性のあるパッケージ間で競合を解消するのに役立ちます。

たとえば、PenWin ユニットは PenWin.dll を参照します。ほとんどのプロジェクトでは PenWin を使用せず、また、ほとんどのコンピュータにも PenWin.dll はインストールされていません。このような理由から、PenWin ユニットは、vcl に弱くパッケージ化されています。PenWin と vcl パッケージを使用するプロジェクトをコンパイルすると、PenWin が vcl70.dcp からコピーされ、プロジェクトに直接バインドされます。結果として生成される実行可能ファイルは PenWin.dll に静的にリンクされています。

PenWin が弱くパッケージ化されなかった場合は、2 つの問題が発生します。第 1 に、vcl 自身が PenWin.dll に静的にリンクされてしまうので、PenWin.dll がインストールされていないコンピュータには vcl を読み込むことができなくなってしまいます。第 2 に、PenWin を含んだパッケージを作成しようとした場合、そのパッケージと vcl の両方に PenWin ユニットが含まれてしまうため、コンパイル エラーが発生します。このように、弱いパッケージ化がなければ、PenWin を vcl の標準配布物に含めることはできません。

C++Builder の場合:

#pragma package(smart_init, weak) 指令は、パッケージの .bpi ファイルおよび .bpl ファイルへの .obj ファイルの格納方法に影響を及します (コンパイラとリンカで生成されるファイルについては、「パッケージと標準 DLL」を参照)。#pragma package(smart_init, weak) がユニット ファイルで検出された場合、リンカはそのユニットを bpl からできるだけ除外し、別のアプリケーションやパッケージで必要になったときには、そのユニットのパッケージ化されていないローカル コピーを作成します。この指令を付けてコンパイルされたユニットは、弱くパッケージ化されていると言われます。

たとえば、ユニットが 1 つだけ(UNIT1)含まれている PACK というパッケージを作成したとしましょう。UNIT1 ではもう他のユニットを使用することはなく、RARE.dll を呼び出すと想定します。パッケージをビルドする際に UNIT1.cpp に #pragma package(smart_init, weak) 指令が記述されていると、UNIT1 は PACK.bpl には含まれません。このため、RARE.dll のコピーを PACK と一緒に配布しなくてもよくなります。ただし、UNIT1 は依然として PACK.bpi に含まれています。PACK を使用する別のパッケージやアプリケーションから UNIT1 が参照されている場合は、それが PACK.bpi からコピーされ、プロジェクトに直接リンクされます。

ここで、2 つ目のユニット UNIT2 を PACK に追加するとしましょう。UNIT2 は UNIT1 を使用するとします。今度は、PACK のコンパイル時に UNIT1.cpp に #pragma package(smart_init, weak) を指定したとしても、リンク後、UNIT1 は PACK.bpl に含まれます。しかし、UNIT1 を参照している他のパッケージやアプリケーションでは、(パッケージ化されていない)コピーを PACK.bpi から取得して使用します。

メモ: #pragma package(smart_init, weak) 指令が含まれたユニット ファイルには、グローバル変数を定義しないでください。

#pragma package(smart_init, weak) 指令は、他の C++Builder プログラマに bpl を配布する開発者向けの高度な機能です。この機能は、使用頻度の低い DLL の配布を避け、また、同じ外部ライブラリに依存する可能性のあるパッケージ間で競合を解消するのに役立ちます。

たとえば、PenWin ユニットは PenWin.dll を参照します。ほとんどのプロジェクトでは PenWin を使用せず、また、ほとんどのコンピュータにも PenWin.dll はインストールされていません。このような理由から、PenWin ユニットは、vcl に弱くパッケージ化されています。PenWin と vcl パッケージを使用するプロジェクトをリンクすると、PenWin が vcl60.bpi からコピーされ、プロジェクトに直接バインドされます。結果として生成される実行可能ファイルは PenWin.dll に静的にリンクされています。

PenWin が弱くパッケージ化されなかった場合は、2 つの問題が発生します。第 1 に、vcl 自身が PenWin.dll に静的にリンクされてしまうので、PenWin.dll がインストールされていないコンピュータには vcl を読み込むことができなくなってしまいます。第 2 に、PenWin を含んだパッケージを作成しようとした場合、そのパッケージと vcl の両方に PenWin ユニットが含まれてしまうため、ビルド エラーが発生します。このように、弱いパッケージ化がなければ、PenWin を vcl の標準配布物に含めることはできません。

関連項目