19.1.3 COBOLプログラムからCプログラムを呼び出す方法
COBOLプログラムからCプログラムを呼ぶときの規則を示します。
(1) COBOLからCを呼ぶときの規則
-
COBOLプログラムを-DebugInf,-DebugInf,Trace,-DebugCompati,-DebugData,-TDInf,-CVInfまたは-DebugRangeオプション指定でコンパイルし,Cプログラムで例外処理をした場合,異常終了時の結果は保証しません。
-
Cプログラム内で宣言された外部変数,およびCOBOLプログラム内の外部属性を持つデータ項目はそれぞれのプログラムで参照できます。外部属性を持つデータ項目の参照方法については,「19.1.5 外部属性を持つデータ項目の共用」を参照してください。
-
COBOLプログラムは,Cプログラムのreturn文で設定された関数値をRETURN-CODE特殊レジスタとして参照できます。Cプログラムが返す関数値の有効な範囲については,「17.2 復帰コードと返却項目」を参照してください。
-
COBOLプログラムからCプログラムを呼び出して,内部浮動小数点項目の引数渡しをする場合,受け取りのデータ型は次の規則に従う必要があります。
-
単精度内部浮動小数点項目の引数渡しをする場合,受け取りのデータ型はfloatとする。
-
倍精度内部浮動小数点項目,または浮動小数点数字定数の引数渡しをする場合,受け取りのデータ型はdoubleとする。
-
-
CALL文にRETURNING指定がある場合,Cプログラムの戻り値は,そのデータ項目に対応したC言語のデータ型にする必要があります。RETURNING指定がない場合はint型にする必要があります。
-
COBOLプログラムでは,Cプログラムのreturn文で設定した戻り値を,呼び出されたCALL文に指定したRETURNINGのデータ項目として参照できます。RETURNING指定がない場合はRETURN-CODE特殊レジスタで参照します。
-
CALL 一意名でCプログラムを呼ぶ場合,次の点に注意する必要があります。
-
共用ライブラリ中のCプログラムを呼ぶ場合,共用ライブラリのエクスポート情報中にプログラム名がなければなりません。このため,リンク時にオプションの指定によってプログラムをエクスポートしなかった場合,そのプログラムはCALL 一意名では呼び出せません。
-
(2) Cプログラムの型とCOBOLでの宣言
Cプログラムのデータ型と,対応するCOBOLのデータ項目の型を,次に示します。
|
Cプログラムのデータ型 |
対応するCOBOLのデータ項目の型 |
||
|---|---|---|---|
|
unsigned char |
-Bin1Byte指定あり |
符号なし2進項目(1〜2けた) |
9(1) COMP 〜 9(2) COMP |
|
-Bin1Byte指定なし |
9(1) COMP-X 〜 9(2) COMP-X |
||
|
− |
英数字項目(1けた) |
X(1) |
|
|
char |
-Bin1Byte指定あり |
符号付き2進項目(1〜2けた) |
S9(1) COMP 〜 S9(2) COMP※4 |
|
− |
英数字項目(1けた) |
X(1) |
|
|
unsigned short |
− |
符号なし2進項目(3〜4けた) |
9(3) COMP 〜 9(4) COMP 9(3) COMP-X 〜 9(4) COMP-X |
|
short |
− |
符号付き2進項目(3〜4けた) |
S9(3) COMP 〜 S9(4) COMP |
|
unsigned int |
− |
符号なし2進項目(5〜9けた) |
9(5) COMP 〜 9(9) COMP 9(5) COMP-X 〜 9(9) COMP-X |
|
int |
− |
符号付き2進項目(5〜9けた) |
S9(5) COMP 〜 S9(9) COMP |
|
unsigned long |
− |
符号なし2進項目(5〜9けた)※1 |
9(5) COMP 〜 9(9) COMP 9(5) COMP-X 〜 9(9) COMP-X |
|
符号なし2進項目(10〜18けた)※2 |
9(10) COMP 〜 9(18) COMP 9(10) COMP-X 〜 9(18) COMP-X |
||
|
long |
− |
符号付き2進項目(5〜9けた)※1 |
S9(5) COMP 〜 S9(9) COMP |
|
符号付き2進項目(10〜18けた)※2 |
S9(10) COMP 〜 S9(18) COMP |
||
|
unsigned long long |
− |
符号なし2進項目(10〜18けた) |
9(10) COMP 〜 9(18) COMP 9(10) COMP-X 〜 9(18) COMP-X |
|
long long |
− |
符号付き2進項目(10〜18けた) |
S9(10) COMP 〜 S9(18) COMP |
|
float |
− |
単精度内部浮動小数点数字項目 |
COMP-1 |
|
double |
− |
倍精度内部浮動小数点数字項目 |
COMP-2 |
|
ポインタ型 |
− |
アドレス名,アドレスデータ項目 |
ADDRESS |
|
配列型 |
− |
アドレスデータ項目 |
ADDRESS |
|
構造体※3 |
− |
集団項目 |
− |
- (凡例)
-
−:該当しない
注※1 AIX(32)およびLinux(x86)の場合です。
注※2 AIX(64)およびLinux(x64)の場合です。
- 注※3
-
COBOLの集団項目を受け渡しする場合,Cプログラムでの境界調整を考慮して引数のデータ項目を定義する必要があります。
COBOLの集団項目は,標準では各基本項目がすき間なく配置されるのに対し,Cプログラムでは計算機固有の境界に従って配置されます。このため,あらかじめ境界調整される分の未使用領域を定義しておくなど,計算機固有の境界調整を意識したデータを定義しておくことを推奨します。
なお,COBOLでは,SYNCHRONIZED句を指定することで計算機固有の境界調整に従って各基本項目を配置できます。
Linux(x64)では,プラットフォームの規約とCOBOL言語仕様の差異によって,従属項目として内部浮動小数点項目をもつ16バイト以下の集団項目を値渡し(BY VALUE)の引数および返却項目に指定した場合,C言語プログラムとの間での引数および返却項目の受け渡しは保証しません。
このような場合,次に示すどれかの方法でプログラムを修正する必要があります。
・集団項目ではなく同じサイズの文字列項目として値の受け渡しをする。
・値渡しではなく参照渡し(BY REFERENCE)または内容渡し(BY CONTENT)に変更する。
・集団項目のサイズが16バイトを超えるようにする。
なお,-Lx64ConventionCheckオプションを指定すると,次の条件を満たす場合に警告レベルのエラーメッセージが出力されます。
1. サイズが16バイト以下の集団項目を値渡しの引数および返却項目に指定している。
2. 1.の集団項目の従属項目に内部浮動小数点項目がある。
Linux(x86)では,プラットフォームの規約とCOBOL言語仕様の差異によって,サイズが1バイトのCOBOL集団項目とサイズが1バイトのC言語構造体との間で返却項目の受け渡しはできません。
AIXでは,プラットフォームの規約とCOBOL言語仕様の差異によって,サイズが1バイトのCOBOL集団項目とサイズが1バイトのC言語構造体との間で値渡し(BY VALUE)の引数および返却項目の受け渡しはできません。
注※4 符号修飾子を省略したとき,unsigned charと解釈するCコンパイラを使用する場合,明示的にsigned charと書くか,または適切なCコンパイラのオプションを指定してsigned charと解釈されるようにする必要があります。
(3) 引数の受け渡し
COBOLプログラムからCプログラムへ引数を渡す方法を,次に示します。
(a) 引数をポインタ型で引き渡す例
- COBOLプログラム
: WORKING-STORAGE SECTION. 01 CNT PIC S9(9) USAGE COMP. 01 STR. 02 STRCHAR PIC X(79). 02 FILLER PIC X VALUE LOW-VALUE. : PROCEDURE DIVISION. : CALL 'sample2' USING BY REFERENCE CNT STR. :- Cプログラム
int sample2(int *cnt, char *str) { : return(0); }
-
COBOLプログラムからCプログラムにBY VALUE指定なしで引き渡す引数は,すべてポインタ型として引き渡されます。このため,Cプログラム内で受け取る引数は,すべてポインタ型で宣言する必要があります。
-
Cプログラムは,COBOLプログラムから数字項目を受け取る場合,内部・外部10進項目,内部・外部浮動小数点数字項目などの数字属性を意識する必要があります。
(b) 引数を値渡しで引き渡す例
- COBOLプログラム
: WORKING-STORAGE SECTION. 01 CNT PIC S9(9) USAGE COMP. 01 STR PIC X(1). : PROCEDURE DIVISION. : CALL 'sample2' USING BY VALUE CNT STR. :- Cプログラム
int sample2(int cnt, char str) { : return(0); }
-
Cプログラム内で受け取る引数は,BY VALUE指定の場合は値渡しで受け取ります。CALL文のBY VALUEで指定したCOBOLのデータ項目に対するC言語のデータ型の対応については,「表19‒1 COBOLのデータ項目とCプログラムの型の対応」を参照してください。
-
BY VALUE指定時,引数は次のように設定されます。
-
単精度内部浮動小数点数字項目は4バイトで,倍精度内部浮動小数点数字項目は8バイトで設定されます。
-
数字定数,およびZEROは4バイトの2進形式として設定されます。
-
浮動小数点数字定数は倍精度浮動小数点形式として設定されます。
-
(c) CALL文の引数にADDRESS OF 一意名,LENGTH OF 一意名を指定した例
- COBOL主プログラム
IDENTIFICATION DIVISION. PROGRAM-ID. SAMPLE1. DATA DIVISION. WORKING-STORAGE SECTION. 01 WK-1. 02 W01 PIC X(30) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234'. 02 FILLER PIC X VALUE LOW-VALUE. …5. PROCEDURE DIVISION. CALL 'SAMPLE2' USING BY REFERENCE WK-1. …1. CALL 'SAMPLE3' USING BY REFERENCE ADDRESS OF WK-1. …2. CALL 'SAMPLE4' USING BY CONTENT LENGTH OF WK-1. …3. CALL 'SAMPLE5' USING BY VALUE LENGTH OF WK-1. …4. STOP RUN. END PROGRAM SAMPLE1.- C副プログラム
#include <stdio.h> int SAMPLE2(char *p_ptr_r) { printf("first char(r) =(%s)\n",p_ptr_r); … 1. : } int SAMPLE3(char **p_ptr_ra) { printf("first char(ra)=(%s)\n",*p_ptr_ra); … 2. : } int SAMPLE4( int *p_ptr_cl /* この引数の型は32bitアプリケーションの場合 */ /* 64bitアプリケーションの場合は long long * */ ) { printf("length(p) =(%d)\n",*p_ptr_cl); … 3. /* この書式指定は32bitアプリケーションの場合 */ /* 64bitアプリケーションの場合 %lld */ : } int SAMPLE5( int p_ptr_vl /* この引数の型は32bitアプリケーションの場合 */ /* 64bitアプリケーションの場合は long long */ ) { printf("length(p) =(%d)\n",p_ptr_vl); … 4. /* この書式指定は32bitアプリケーションの場合 */ /* 64bitアプリケーションの場合 %lld */ : }
-
BY REFERENCE指定のCALL文で渡される値は,指定された一意名のアドレスです。
-
ADDRESS OFで修飾した場合に渡される値は,一意名のアドレスではなく,一意名のアドレスが入っている領域のアドレスとなります。
-
LENGTH OFで修飾したCONTENT指定では,一意名の長さが入っている領域のアドレスが渡されます。
-
LENGTH OFで修飾したVALUE指定では,一意名の長さが値として渡されます。
-
Cプログラム中で文字列として参照するため,COBOLプログラム中で英数字項目の終端にNULL文字(X'00')を設定しています。
- BY REFERENCE指定で渡される引数の値
-
- 実行結果
first char(r) =(ABCDEFGHIJKLMNOPQRSTUVWXYZ1234) : first char(ra)=(ABCDEFGHIJKLMNOPQRSTUVWXYZ1234) : length(p) =(31) : length(p) =(31) :
(4) 戻り値の受け渡し
CプログラムからCOBOLプログラムへ戻り値を返す方法を,次に示します。
(a) 整数型のデータ項目をリターンする例
- COBOLプログラム
WORKING-STORAGE SECTION. 01 RTC PIC S9(9) USAGE COMP. : PROCEDURE DIVISION. : CALL 'sample2' RETURNING RTC.- Cプログラム
int sample2() { int rtc; : return (rtc); }
(b) 構造体型のデータ項目をリターンする例
構造体型のデータ項目をリターンする場合,COBOLプログラムとCプログラムでは境界調整によってデータのマッピング方法が異なることがあるので注意が必要です。
- COBOLプログラム
WORKING-STORAGE SECTION. 01 TBL. 02 A PIC S9(9) USAGE COMP. 02 B PIC X(10). : PROCEDURE DIVISION. : CALL 'sample2' RETURNING TBL.- Cプログラム
struct tbl {int a; char b[10];}; struct tbl sample2() { struct tbl rtn; : return (rtn); }