18.6.2 共用ライブラリに含まれるプログラムの呼び出し方法
(1) 静的なリンク
呼び出し元プログラムのリンク時に共用ライブラリを指定して,呼び出し先プログラム名を解決する方法です。この場合,実行可能ファイルがロードされるときに,共用ライブラリもロードされます。
共用ライブラリを静的にリンクするには,呼び出し元プログラムから定数指定のCALL文で,呼び出し先プログラムの共用ライブラリを呼び出します。
プログラム実行時,リンク時に指定した検索パスに共用ライブラリがないと,プロセス起動エラーとなります。
- (例)
- 副プログラムを含む共用ライブラリがCALL '定数'で呼ばれ,実行可能ファイルの作成時に共用ライブラリを指定してリンクした場合,静的なリンクでの呼び出しとなります。
![[図データ]](figure/wu101370.gif)
(2) 動的なリンク
実行時に呼び出し先プログラムを検索する方式です。
共用ライブラリを動的にリンクするには,呼び出し元プログラムから-DynamicLink,Callオプションを指定した場合のCALL文,または-DynamicLink,IdentCallオプションを指定した場合の一意名指定のCALL文で,呼び出し先プログラムの共用ライブラリを呼び出します。
動的なリンクの場合,CALL文実行時に動的なリンクによって共用ライブラリがロードされます。
- 共用ライブラリのロード条件
- CALL文で副プログラムを呼び出すか,またはADDR関数でプログラムのアドレスを求める場合,次に示すプログラムの優先順位に従ってプログラムが検索され,見つかったプログラムが呼び出されるか,またはアドレスが求められます。プログラムが見つからなかった場合,動的なリンクによって,共用ライブラリがロードされます。
- プログラムの優先順位は次のとおりです。
- 呼び出しできる内側のプログラム
- 静的にリンクされた最外側のプログラム
- すでにロードされている共用ライブラリ中のプログラム
実行性能を重視するシステムでは,検索対象となる共用ライブラリを限定するために,動的なリンクで使用する環境変数の指定は有効です。動的なリンクで使用する環境変数を次に示します。
- CBLLPATH(HP-UX(IPF),HP-UX(IPF64),AIX(32),AIX(64)で有効)
- CBLLSLIB
- システム環境変数LD_LIBRARY_PATH(Linux,Solaris(SPARC)で有効)
- CBLLTAG(AIX(32),AIX(64)で有効)
- 環境変数CBLLPATH(HP-UX(IPF),HP-UX(IPF64),AIX(32),AIX(64)で有効)
- 検索対象となる共用ライブラリのディレクトリを指定します。
- 形式
CBLLPATH=検索ディレクトリ[:検索ディレクトリ]…
- 検索ディレクトリ
- 動的にリンクする共用ライブラリのディレクトリを指定します。
- 規則
- 複数ディレクトリを検索対象とする場合,コロン(:)で区切って指定します。
- 動的なリンクの対象となる共用ライブラリは,次のディレクトリにある共用ライブラリから順に,共用ライブラリの登録順で検索されます。
1.環境変数CBLLPATH設定のディレクトリ下の共用ライブラリ
2.カレントディレクトリ下の共用ライブラリ
- 検索ディレクトリの指定がない場合は,カレントディレクトリ下の共用ライブラリだけが動的なリンクの対象となります。
- 環境変数CBLLPATHに指定した各ディレクトリ名称に,ロード対象の共用ライブラリ名称を付加した文字列長は,終端NULL文字を含めて1,023バイトまでです。
- 環境変数CBLLSLIB
- 検索対象となる共用ライブラリを指定します。
- 形式
CBLLSLIB=共用ライブラリ名称[:共用ライブラリ名称]…
- 共用ライブラリ名称
- 動的にリンクする共用ライブラリの名称を指定します。
- 規則
- 共用ライブラリ名称の指定方法には,共用ライブラリのファイル名称だけを指定する方法と,ディレクトリを含めたファイル名称を指定する方法があります。
- ファイル名称だけを指定した場合,カレントディレクトリの共用ライブラリだけが動的なリンクの対象となります。
- 複数の共用ライブラリを検索対象とする場合,コロン(:)で区切って指定します。コロン(:)で区切られた最後の’/’は無視されます。
- 複数の共用ライブラリを検索対象とする場合,指定した順に検索を行うため,指定順序によって検索時間を短縮できます。
- 注意事項
- LinuxまたはSolaris(SPARC)の場合,環境変数CBLLSLIBにファイル名称だけを指定したとき,カレントディレクトリは検索対象になりませんので,必ず,システム環境変数LD_LIBRARY_PATHで検索パスを設定してください。
- AIX(32)またはAIX(64)の場合,アーカイブ形式の共用ライブラリも指定できます。
- 環境変数CBLLSLIBの指定がない場合,ロード対象の共用ライブラリの検索方法を次に示します。
HP-UX(IPF),HP-UX(IPF64),AIX(32),またはAIX(64)の場合は,環境変数CBLLPATHに指定したディレクトリおよびカレントディレクトリから検索します。
LinuxまたはSolaris(SPARC)の場合,動的なリンクを使用するとき,環境変数CBLLSLIBで共用ライブラリを必ず指定してください。環境変数CBLLSLIBの指定がない場合には,検索する共用ライブラリがないことになります。
- システム環境変数LD_LIBRARY_PATH(Linux,Solaris(SPARC)で有効)
- 共用ライブラリを動的にリンクする場合,検索ディレクトリを指定する環境変数CBLLPATHは使用できません。
- 共用ライブラリの検索ディレクトリを指定する場合,システム環境変数LD_LIBRARY_PATHで検索パスを設定する必要があります。システム環境変数LD_LIBRARY_PATHについては,システムのldコマンドのリファレンスを参照してください。
- 注意事項
- カレントディレクトリを検索ディレクトリとする場合でも,システム環境変数LD_LIBRARY_PATHで検索パスを設定してください。
- 環境変数CBLLTAG(AIX(32),AIX(64)で有効)
- 環境変数CBLLTAGは,動的なリンクの動作を指示するオプションを指定します。
- 形式
CBLLTAG=オプション[:オプション]
- オプション:SO/NOSO,ARMBR/NOARMBR
- 規則
- 複数のオプションを指定する場合はコロン(:)で区切ります。
- この環境変数に指定できるオプションを次に示します。
SO/NOSO
動的なリンクで,検索対象とする共用ライブラリの拡張子を選択できます。
SOを指定した場合は,拡張子「.so」の共用ライブラリを検索対象とします。このオプションの標準値はSOです。
NOSOを指定した場合は,拡張子「.so」の共用ライブラリを検索対象としません。ただし,すでにロードされている共用ライブラリには,このオプションは作用しません。すでにロードされている共用ライブラリとは,次に示す共用ライブラリを指します。
・実行可能ファイル作成時にリンクした共用ライブラリ
・前に呼び出したプログラムのライブラリ作成時にリンクした共用ライブラリ
・ロード関数により,すでにロードされている共用ライブラリ
ARMBR/NOARMBR
動的なリンクで,検索対象とするライブラリ種別を選択できます。
ARMBRを指定した場合は,アーカイブ化された共用ライブラリを検索対象とします。このオプションの標準値はARMBRです。
NOARMBRを指定した場合は,アーカイブ化された共用ライブラリを検索対象としません。
ARMBR/NOARMBRは,すでにロードされているアーカイブ化された共用ライブラリについても有効となります。そのため,NOARMBRを指定した場合は,実行可能ファイル作成時にリンクしたアーカイブ化された共用ライブラリは検索対象になりません。
- 注意事項
- この環境変数を使用する場合は,プログラムの開発環境と実行環境で,必ず,同じオプションを指定してください。
- 環境変数CBLLSLIBに拡張子「.so」の共用ライブラリ指定した場合,環境変数CBLLTAGにNOSOを指定したときでも,環境変数CBLLSLIBに指定された共用ライブラリは検索対象となります。
- NOSO,NOARMBRオプションを指定する場合は,動的なリンクで呼び出すサブプログラムは,次に示す点に注意して作成してください。
指定するオプション | 共用ライブラリファイル作成時の注意点 |
---|
NOSOオプション | 共用ライブラリファイルの拡張子は「.a」で作成してください。 |
NOARMBRオプション | 共用ライブラリファイルは,ldコマンドで作成してください。 ldコマンドで作成した共用ライブラリをarコマンドでアーカイブファイル化した場合は,動的なリンクで呼び出すことができません。 |
- アーカイブ形式の共用ライブラリ(AIX(32),AIX(64)で有効)
- AIX(32)またはAIX(64)では,共用ライブラリをarコマンドによってアーカイブファイルにして(アーカイブ形式の共用ライブラリ),共有オブジェクトのメンバとして扱うことができます。arコマンドの使用例は,「33. 実行可能ファイルと共用ライブラリの作成」を参照してください。
- AIX(32)またはAIX(64)で共用ライブラリを動的にリンクする場合,アーカイブ形式の共用ライブラリ中のプログラムを動的なリンクで呼び出せます。
- ロード対象
- 環境変数CBLLSLIBにアーカイブ形式の共用ライブラリを指定した場合,アーカイブファイルにある共有オブジェクトのメンバがロード対象になります。
- 環境変数CBLLSLIBの指定がない場合,カレントディレクトリおよび環境変数CBLLPATHで指定したディレクトリ下のすべての共用ライブラリがロード対象となります。また,その共用ライブラリがアーカイブ形式の場合,ファイル中の共有オブジェクトのメンバがロード対象となります。
- 注意事項
- ネストされたアーカイブは使用できません(ネストされたアーカイブとは,arコマンドでいったん作成したアーカイブを,さらにarコマンドでアーカイブ化することです)。
- アーカイブ形式の共用ライブラリに同じ名称のメンバが複数存在する場合は,最初のメンバを対象とします。
- アーカイブ形式の共用ライブラリを静的にリンクした場合は,アーカイブ形式でない共用ライブラリを静的にリンクした場合と同じく,リンク時に指定した共用ライブラリが実行開始時にロードされます。
- 指定が必要なライブラリ(HP-UX(IPF),HP-UX(IPF64)で有効)
- 動的なリンクを使用する場合,ELFアクセスライブラリ(libelf.sl)が必要です。
- (例)
- 一意名指定のCALL文での呼び出しの場合は,動的なリンクでの呼び出しとなります。
![[図データ]](figure/wu101380.gif)
- 注意事項
- 環境変数の値は,プログラムで最初に呼ばれたCALL文の実行時に取得した値が,そのプログラム中で有効になります。
(3) 注意事項
- マルチスレッド対応でないCOBOLプログラムの場合,動的にロードされた共用ライブラリは,COBOL実行環境の終了時にアンロードされます。したがって,atexitシステム関数などのように,COBOL実行環境の終了後のタイミングで呼び出される関数を共用ライブラリに登録する場合は,次の点に注意してください。
- COBOL実行環境終了後のタイミングで呼び出される関数は,動的にロードされる共用ライブラリに含まれる関数であってはなりません。動的にロードされた共用ライブラリがアンロードされると,その共用ライブラリに静的にリンクされた共用ライブラリもアンロードされます。この場合,静的にリンクされた共用ライブラリに登録する関数についても注意が必要です。
- 動的にロードされる共用ライブラリのアンロードを抑止するには,環境変数CBLNO_LIBFREEを使用してください。環境変数CBLNO_LIBFREEについては,「18.6.3 共用ライブラリのアンロード」を参照してください。
(4) プログラムのデバッグ
実行可能ファイルに静的にリンクしたCOBOLプログラムと同様に,動的にリンクした共用ライブラリについてもテストデバッガを使用したデバッグができます。
(5) 動的なリンクを使用するプログラム作成時の注意事項
プログラムの作成時には次のような注意が必要になります。
- Cプログラム,または-DynamicLinkオプションを指定しないでコンパイルした呼び出し元プログラムからCALL文で呼び出し先プログラムを呼び出す場合,動的なリンクは行いません。したがって,呼び出し先プログラムは次のような状態でなければなりません。
- 主プログラムに静的にリンクされている。
- すでにロードされた共用ライブラリに含まれる。
- 呼び出し元プログラムと同じ共用ライブラリに含まれる。
また,呼び出し先プログラムが動的にロードされた共用ライブラリにある場合,その共用ライブラリはアンロードされる場合があります。この場合,呼び出し元プログラムを再実行したときの動作は保証しません。
- 動的にロードされる共用ライブラリに,静的にリンクされている共用ライブラリに含まれるCプログラムを呼び出す場合,次の注意が必要になります。
- Cプログラムには,外部属性を持つ変数の実体を定義してはならない。
動的なリンクによってロードされた共用ライブラリは,COBOLの実行環境終了時にアンロードされます。このとき,システムによってアンロード対象の共用ライブラリに静的にリンクされている共用ライブラリもアンロードされます。この場合,外部属性を持つ変数の実体がなくなるため,プログラムが正常に動作しなくなる場合があります。
- Cプログラムで外部属性を持つ変数を参照する場合,その変数の実体はすでに実行されたプログラムで定義しなければなりません。
未実行のプログラムで外部属性を持つ変数の実体が定義されている場合,そのプログラムを含む共用ライブラリがアンロードされる場合があります。このため,外部属性を持つ変数の実体がなくなり,プログラムが正常に動作しない場合があります。
- -DynamicLinkオプションを指定したCOBOLオブジェクトファイルをリンクする場合,-lelfオプションの指定が必要です。ccbl2002コマンドを使用してリンクまで実行する場合,-DynamicLinkオプションを指定していると,ccbl2002コマンドがリンク時に-lelfオプションを仮定します。
- HP-UX(IPF)またはHP-UX(IPF64)の場合,実行可能ファイル中に存在するプログラムを動的なリンクで呼び出すときは,実行可能ファイル作成(リンク)時に,-Eリンカオプションの指定が必要です。
ccbl2002コマンドを使用してリンクまで実行する場合,-DynamicLink,Callオプションを指定していると,ccbl2002コマンドがリンク時に-Eリンカオプションを仮定します。
-Eリンカオプションについては,システムのマニュアルを参照してください。
- Linuxの場合,実行可能ファイル中に存在するプログラムを動的なリンクで呼び出すときは,実行可能ファイル作成(リンク)時に,-Eまたは-export-dynamicリンカオプションの指定が必要です。
ccbl2002コマンドを使用してリンクまで実行する場合,-DynamicLinkオプションを指定していると,ccbl2002コマンドがリンク時に-Eリンカオプションを仮定します。
-Eリンカオプションについては,システムのマニュアルを参照してください。
- AIX(32),AIX(64)の場合,動的なリンクを使用時に作業場所節のデータ記述項にEXTERNAL句を指定し,データを共用するプログラムを使用するときは,実行可能ファイル作成時に,次のリンカオプションを指定してください。
- -bexpallオプションまたは-bEオプション
EXTERNAL指定のデータ項目の名称を外部シンボルとしてエクスポートする場合に指定します。
すべてのシンボルをエクスポートする場合は,-bexpallオプションを指定します。エクスポートするシンボルを限定する場合は,-bEオプションでエクスポートするEXTERNAL指定のデータ項目の名称を指定したファイルを指定します。
- -brtlオプション
実行時リンクを使用する場合に指定します。
すべてのシンボルをエクスポートして,EXTERNAL句を用いたデータの共用を行う指定例を次に示します。
- (例)
- ccbl2002 -DynamicLink,Call -OutputFile prog1 prog1.cbl -Wl,-bexpall,-brtl
リンカオプションについては,システムのマニュアルのldコマンドに関する説明を参照してください。
- 利用者定義関数を含めた共用ライブラリは,動的なリンク(プログラム呼び出した時にメモリにロードされるリンク方法)では呼び出せません。
プログラムの作成方法については,「33. 実行可能ファイルと共用ライブラリの作成」を参照してください。
(6) 動的なリンクを使用する場合の注意事項
動的なリンクでは,独自に共用ライブラリのロードやアンロードを管理しています。そのため,プログラムの実行中に,共用ライブラリのロードやアンロードに関連するシステム関数※を,ユーザプログラムから呼び出してはなりません。
- 注※
- 共用ライブラリのロードやアンロードに関連するシステム関数は,次のとおりです。
- HP-UX(IPF),HP-UX(IPF64)の場合
- shl_load,shl_unload
- AIX(32),AIX(64),Linux,Solaris(SPARC)の場合
- dlopen,dlclose