プライマリ・コンテンツに移動
Pro*C/C++プログラマーズ・ガイド
12c リリース1(12.1)
B71397-03
目次へ移動
目次
索引へ移動
索引

前
次

プリコンパイル済ヘッダー・ファイル

プリコンパイル済ヘッダー・ファイルを使用すると、多数の#include文を含むヘッダー・ファイルをプリコンパイルすることで、時間とリソースを節約できます。この機能を使用する手順は次の2つです。

この機能は、多数のモジュールで構成される大型アプリケーションに使用してください。

プリコンパイラ・オプションをHEADER=hdrに設定すると、次のように指定されます。

このオプションを入力できるのは、構成ファイルまたはコマンドラインのみです。HEADERにはデフォルト値はありませんが、入力ヘッダーの拡張子は.hである必要があります。

プリコンパイル済ヘッダー・ファイルの作成

ヘッダー・ファイルtop.hを作成するとします。このファイルは、HEADER=hdrを指定してプリコンパイルできます。

proc HEADER=hdr INAME=top.h

注意:

拡張子は.hにする必要があります。INAME値には、「/」や「..」などの絶対パス要素や相対パス要素は使用できません。

Pro*C/C++により、指定した入力ファイルtop.hがプリコンパイルされ、同じディレクトリに新しいプリコンパイル済ヘッダー・ファイルtop.hdrが生成されます。出力ファイルtop.hdrは、#include文による検索対象となるディレクトリに移動できます。

注意:

出力ファイル名の指定にはONAMEオプションを使用しないでください。HEADERとともに使用すると無視されます。

プリコンパイル済ヘッダー・ファイルの使用

HEADERオプションには、プリコンパイル対象のアプリケーション・ファイルと同じ値を使用してください。simple.pcに次のファイルが含まれているとします。

#include <top.h>
...

また、top.hに次のファイルが含まれているとします。

#include <a.h>
#include <b.h>
#include <c.h>
...

次の方法でプリコンパイルします。

proc HEADER=hdr INAME=simple.pc

Pro*C/C++では、#include top.h文の読込み時に対応するtop.hdrファイルが検索され、top.hが再度プリコンパイルされるかわりに、そのファイルからデータがインスタンス化されます。

注意:

プリコンパイル済ヘッダー・ファイルは、常に入力ヘッダー・ファイルのかわりに使用されます。入力(.h)ファイルがインクルード・ディレクトリの標準検索階層の最初に表示されている場合も同様です。

この項の例では、いくつかの異なるケースを示します。

冗長なファイル・インクルード

次の2つのケースでは、考えられる2つの冗長なファイル・インクルードを示します。

ケース1: 最上位のヘッダー・ファイルのインクルード

プリコンパイル済ヘッダー・ファイルは、#includeディレクティブを使用してインクルードされた回数に関係なく、一度のみインスタンス化されます。

前述の例と同様に、HEADERの値をhdrに設定し、最上位のヘッダー・ファイルtop.hをプリコンパイルするとします。次に、そのヘッダー・ファイルに対して、複数の#includeディレクティブをプログラムに記述します。

#include <top.h>
#include <top.h>
main(){}

top.hの最初の#includeが発生すると、プリコンパイル済ヘッダー・ファイルtop.hdrがインスタンス化されます。同じヘッダー・ファイルの2番目のインクルードは、冗長であるために無視されます。

ケース2: ネストされたヘッダー・ファイルのインクルード

ファイルa.hに次の文が含まれているとします。

#include <b.h>

前述の例と同様にHEADERを指定して、そのヘッダー・ファイルをプリコンパイルします。Pro*C/C++では、a.hとb.hの両方がプリコンパイルされ、a.hdrが生成されます。

次に、このPro*C/C++プログラムをプリコンパイルするとします。

#include <a.h>
#include <b.h>
main(){}

a.hの#includeが発生すると、a.hが再度プリコンパイルされるかわりに、プリコンパイル済ヘッダー・ファイルa.hdrがインスタンス化されます。このインスタンス化には、b.hの内容全体も含まれます。

b.hはa.hのプリコンパイルに含まれ、a.hdrはインスタンス化されているため、プログラムに指定されているb.hの後続の#includeは冗長になり、無視されます。

複数のプリコンパイル済ヘッダー・ファイル

Pro*C/C++では、1回のプリコンパイルで複数の異なるプリコンパイル済ヘッダー・ファイルをインスタンス化できます。ただし、複数のプリコンパイル済ヘッダー・ファイルが共通のヘッダー・ファイルを共有している場合は、次の点に注意してください。

たとえば、topA.hに次の行が含まれているとします。

#include <a.h>
#include <c.h>

また、topB.hには次の行が含まれているとします。

#include <b.h>
#include <c.h>

topA.hおよびtopB.hの両方で、同じ共通ヘッダー・ファイルc.hがインクルードされています。同じHEADER値を指定してtopA.hとtopB.hをプリコンパイルすると、topA.hdrおよびtopB.hdrが生成されます。しかし、両方にc.hの内容全体が含まれています。

次のようなPro*C/C++プログラムがあるとします。

#include <topA.h>
#include <topB.h>
main(){}

プリコンパイル済ヘッダー・ファイルtopA.hdrおよびtopB.hdrの両方が、前述の例と同様にインスタンス化されます。ただし、両方で共通ヘッダー・ファイルc.hが共有されるため、そのファイルの内容は2回インスタンス化されます。

Pro*C/C++では、プリコンパイル済ヘッダー・ファイル間のファイルの共有を判断できません。各プリコンパイル済ヘッダー・ファイルには、一意のヘッダー・セットをインクルードします。ヘッダーの共有はできるだけ避けてください。共有すると、プリコンパイルが低速になり、メモリー使用量が増加するため、プリコンパイル済ヘッダー・ファイルを使用する意味がなくなります。

ヘッダー・ファイルのリスト

ORACLE_BASE\ORACLE_HOME\precomp\publicディレクトリには、Pro*C/C++ヘッダー・ファイルが含まれています。表5-3は、ヘッダー・ファイルのリストと説明です。

表5-3 ヘッダー・ファイル

ヘッダー・ファイル 説明

oraca.h

Oracle通信領域(ORACA)が含まれています。これは、ランタイム・エラーの診断と、プログラムでの様々なOracle Database 10gリソースの使用の監視に役立ちます。

sql2oci.h

SQLLIB関数が含まれています。これらの関数により、Oracle Call Interface(OCI)環境ハンドルとOCIサービス・コンテキストをPro*C/C++アプリケーションで取得できます。

sqlapr.h

OCIとともに使用できる外部関数用のANSIプロトタイプが含まれています。

sqlca.h

ランタイム・エラーの診断に役立つSQLコミュニケーション領域(SQLCA)が含まれています。SQLCAは、実行可能なSQL文が実行されるたびに更新されます。

sqlcpr.h

Pro*C/C++で生成される、SQLLIB関数用のプラットフォーム固有のANSIプロトタイプが含まれています。デフォルトでは、Pro*C/C++は、SQLプログラミング・コールの完全な関数プロトタイプをサポートしていません。この機能が必要な場合、アプリケーション・ソース・ファイル内のすべてのEXEC SQL文の前にsqlcpr.hを含める必要があります。

oraca.h

Oracle通信領域(ORACA)が含まれています。これは、ランタイム・エラーの診断と、プログラムでの様々なOracle Database 10gリソースの使用の監視に役立ちます。

sql2oci.h

SQLLIB関数が含まれています。これらの関数により、Oracle Call Interface(OCI)環境ハンドルとOCIサービス・コンテキストをPro*C/C++アプリケーションで取得できます。

sqlapr.h

OCIとともに使用できる外部関数用のANSIプロトタイプが含まれています。

オプションの効果

アプリケーションのプリコンパイル時には、次のプリコンパイラ・オプションを使用できます。

DEFINEおよびINCLUDEオプション

プリコンパイル済ヘッダーを使用してプリコンパイルするときには、DEFINEとINCLUDEの値を、プリコンパイル済ヘッダー・ファイルの作成時と同じ値にする必要があります。DEFINEまたはINCLUDEの値を変更した場合は、プリコンパイル済ヘッダー・ファイルを再作成する必要があります。

開発環境を変更した場合も、プリコンパイル済ヘッダー・ファイルを再作成する必要があります。

シングル・ユーザーの場合

シングル・ユーザーの場合を考えてみます。DEFINEまたはINCLUDEオプションの値を変更した場合、プリコンパイル済ヘッダー・ファイルの内容は、その後に実行されるPro*C/C++プリコンパイルでは正常に使用できなくなります。

DEFINEおよびINCLUDE、DEFINEまたはINCLUDEオプションの値を変更しているため、プリコンパイル済ヘッダー・ファイルの内容は、#includeディレクティブの対応する.hファイルが正常に処理された場合の標準的な結果と一致しなくなります。

つまり、DEFINEおよびINCLUDE、DEFINEまたはINCLUDEオプションの値を変更した場合は、プリコンパイル済ヘッダー・ファイルを再作成し、それを使用するPro*C/C++プログラムを再度プリコンパイルする必要があります。

関連項目:

マルチ・ユーザーの場合

AおよびBという2人のユーザーがいる場合を考えてみます。AとBはまったく異なる環境で開発しているため、DEFINEおよびINCLUDEオプションの値もまったく異なっています。

ユーザーAは、共通ヘッダー・ファイルcommon.hをプリコンパイルし、プリコンパイル済ヘッダー・ファイルcommon.hdrAを作成します。ユーザーBも同じヘッダー・ファイルをプリコンパイルして、common.hdrBを作成します。ただし、両者の環境が異なるため、2人のユーザーが使用したDEFINEおよびINCLUDEオプションの値も異なります。そのため、ユーザーAとBが作成したcommon.hdrの内容が同じになるとはかぎりません。

要約

A> proc HEADER=hdrA DEFINE=<A macros> INCLUDE=<A dirs> common.h

B> proc HEADER=hdrB DEFINE=<B macros> INCLUDE=<B dirs> common.h

異なる環境で作成されたため、生成されたプリコンパイル済ヘッダー・ファイルcommon.hdrAはcommon.hdrBと同等でない場合があります。つまり、ユーザーAとユーザーBが、相手の作成したcommon.hdrを使用しても、それぞれの開発環境でPro*C/C++プログラムが正常にプリコンパイルされるとはかぎりません。

したがって、プリコンパイル済ヘッダー・ファイルを、異なるユーザー間および異なる開発環境間で共有または交換する場合には、注意が必要です。

CODEおよびPARSEオプション

Pro*C/C++では、hpph++などの拡張子が付いたC++ヘッダー・ファイルは検索されません。このため、ヘッダー・ファイルのプリコンパイル時には、CODE=CPPを使用しないでください。アプリケーションのプリコンパイル時にCPP値を使用できるのは、ソース・コードに.hヘッダー・ファイルのみが含まれる場合にかぎります。

プリコンパイル済ヘッダー・ファイルの作成時、あるいはモジュールのプリコンパイル時には、PARSEオプションに使用できる値はFULLまたはPARTIALのみです。値FULLは、PARTIALより高い値とみなされます。モジュールのプリコンパイル時に使用するPARSEの値は、プリコンパイル済ヘッダー・ファイルの作成時の値以下にする必要があります。

注意:

PARSE=FULLを指定してプリコンパイル済ヘッダー・ファイルをプリコンパイルしてから、PARSE=PARTIALを指定してモジュールをプリコンパイルする場合は、ホスト変数を宣言部中で宣言する必要があります。C++コードは、PARSE=PARTIALを指定した場合にのみ認識されます。

PARTIALに次のPARSEオプションを指定してヘッダー・ファイルをプリコンパイルするとします。

proc HEADER=hdr PARSE=PARTIAL file.h

次に、PARSEをFULLに設定し、そのヘッダー・ファイルを含むプログラムをプリコンパイルします。

proc HEADER=hdr PARSE=FULL program.pc

ファイル.hはPARSEオプションにPARTIALを設定してプリコンパイルしたため、一部のヘッダー・ファイルは処理されていません。このため、未処理部分が参照された場合は、Pro*C/C++プログラムのプリコンパイル時にエラーが発生する可能性があります。

具体例として、ファイル.hに次のコードが含まれているとします。

#define LENGTH 10
typedef int myint;

program.pcに、次の小さいプログラムが含まれているとします。

#include <file.h>
main()
{
     VARCHAR ename[LENGTH];
     myint empno = ...;
     EXEC SQL SELECT ename INTO :ename WHERE JOB = :empno;
}

ファイル.hのプリコンパイル時にPARSEがPARTIALに設定されているため、typedefは処理されずにLENGTHマクロのみが処理されます。

VARCHARの宣言と宣言以後のホスト変数としての使用は、正常に行われます。ただし、Pro*C/C++ではmyint型宣言が処理されないため、empnoホスト変数を使用できません。

PARSEオプションをFULLに設定してヘッダー・ファイルをプリコンパイルしてから、PARSEオプションをPARTIALに設定してプログラムをプリコンパイルすると、正常に動作します。ただし、ホスト変数は明示的な宣言部中で宣言する必要があります。

使用上の注意

プリコンパイル済のヘッダーから生成された出力ファイルの形式は、リリースごとに異なる可能性があります。Pro*C/C++では、プリコンパイル済ヘッダー・ファイルの出力の生成に使用されたプリコンパイラのバージョンを判断できません。

このため、プリコンパイル済ヘッダー・ファイルを使用したプリコンパイル時に、エラーまたは他の予期しない動作を回避するために、Pro*C/C++のリリースのアップグレード時には、対応するヘッダー・ファイルを再度プリコンパイルしてファイルを再生成することをお薦めします。

ヘッダー・ファイルをプリコンパイルして生成された出力ファイルには、移植性がありません。つまり、ヘッダー・ファイルのプリコンパイルにより生成された出力ファイルは、プラットフォーム間で転送できず、別のヘッダー・ファイルまたはPro*C/C++プログラムのプリコンパイル時に使用できません。