19.1.2 CプログラムからCOBOLプログラムを呼び出す方法

CプログラムからCOBOLプログラムを呼ぶときの規則を示します。

<この項の構成>
(1) CからCOBOLを呼ぶときの規則
(2) COBOLのデータ項目とCプログラムの型の対応
(3) 引数の受け渡し
(4) 戻り値の受け渡し

(1) CからCOBOLを呼ぶときの規則

(2) COBOLのデータ項目とCプログラムの型の対応

COBOLとCのデータ型の対応を,次に示します。引数や戻り値などでデータを受け渡す場合は,この規則に従う必要があります。

表19-1 COBOLのデータ項目とCプログラムの型の対応

COBOLC
charunsigned charshortunsigned shortint,
long
unsigned int,
unsigned long
long long15unsigned long long15floatdoubleポインタ構造体
固定長集団項目        ×× ※1
可変長集団項目        ×× ×
英字項目22      ××  
英数字項目22      ××  
英数字編集項目        ××  
外部10進項目33      ××  
内部10進項目        ××  
2進項目4164556116111313××  
COMP-X77889129121414××  
数字編集項目        ××  
外部浮動小数点数字項目        ××  
単精度内部浮動小数点数字項目××××××××※10×××
倍精度内部浮動小数点数字項目×××××××××※10××
アドレスデータ項目        ×× 
指標データ項目        ××  
日本語項目        ××  
日本語編集項目        ××  
外部ブール項目        ××  
内部ブール項目        ××  
英数字定数※2※2      ××  
数字定数       ××  
浮動小数点数字定数×××××××××××
ZERO       ××  
NULL        ×× 
オブジェクト参照項目        ××  
強く型付けされた集団項目        ××  
(凡例)
○:指定できる
空白:受け渡しできるかどうかはプラットフォームに依存するため,動作保証についてはユーザ責任とする
×:指定してはならない。指定したときの結果は保証しない
注※1
COBOLの集団項目を受け渡しする場合,Cプログラムでの境界調整を考慮して引数のデータ項目を定義する必要があります。
COBOLの集団項目は,標準では各基本項目がすき間なく配置されるのに対し,Cプログラムでは計算機固有の境界に従って配置されます。このため,あらかじめ境界調整される分の未使用領域を定義しておくなど,計算機固有の境界調整を意識したデータを定義しておくことを推奨します。
なお,COBOLでは,SYNCHRONIZED句を指定することで計算機固有の境界調整に従って各基本項目を配置できます。
HP-UX(IPF),HP-UX(IPF64),およびLinux(IPF64)では,プラットフォームの規約とCOBOL言語仕様の差異によって,C言語モジュールとの間で次の構造体を値渡しの引数,または返却値として受け渡しした場合の動作は保証しません。
・float型のメンバだけで構成された構造体
・double型のメンバだけで構成された構造体
Linux(x64)では,プラットフォームの規約とCOBOL言語仕様の差異によって,従属項目として内部浮動小数点項目をもつ16バイト以下の集団項目を値渡し(BY VALUE)の引数および返却項目に指定した場合,C言語プログラムとの間での引数および返却項目の受け渡しは保証しません。
このような場合,次に示すどれかの方法でプログラムを修正する必要があります。
・集団項目ではなく同じサイズの文字列項目として値の受け渡しをする。
・値渡しではなく参照渡し(BY REFERENCE)または内容渡し(BY CONTENT)に変更する。
・集団項目のサイズが16バイトを超えるようにする。
なお,-Lx64ConventionCheckオプションを指定すると,次の条件を満たす場合に警告レベルのエラーメッセージが出力されます。
1. サイズが16バイト以下の集団項目を値渡しの引数および返却項目に指定している。
2. 1.の集団項目の従属項目に内部浮動小数点項目がある。
Linux(x86)では,プラットフォームの規約とCOBOL言語仕様の差異によって,サイズが1バイトのCOBOL集団項目とサイズが1バイトのC言語構造体との間で返却項目の受け渡しはできません。
HP-UX(IPF),HP-UX(IPF64),AIX(32),AIX(64),およびSolaris(SPARC)では,プラットフォームの規約とCOBOL言語仕様の差異によって,サイズが1バイトのCOBOL集団項目とサイズが1バイトのC言語構造体との間で値渡し(BY VALUE)の引数および返却項目の受け渡しはできません。
注※2
標準文字集合で1文字の場合はchar型,2文字以上の場合は次の構造体と対応づけます(nは文字数,nameは任意のフィールド名とします)。
struct {
  char name[n];
};
注※3 SEPARATE指定なしの1けたです。
注※4 -Bin1Byteオプションの指定がある場合,1~2けた(割り当てられる記憶域のサイズが1バイト)の整数です。
注※5
注※6
UNIX32の場合,5~9けたの整数です。
UNIX64の場合,intまたはunsigned intのとき,5~9けたの整数です。
注※7 割り当てられる記憶域のサイズが1バイトの場合,指定できます。
注※8 割り当てられる記憶域のサイズが2バイトの場合,指定できます。
注※9
UNIX32の場合,割り当てられる記憶域のサイズが4バイトの場合,指定できます。
UNIX64の場合,intまたはunsigned intのとき,割り当てられる記憶域のサイズが4バイトの場合,指定できます。
注※10 CプログラムからCOBOLプログラムに引数を渡す場合,プロトタイプ宣言が必要です。
注※11 UNIX64の場合,longおよびunsigned longのとき,10~18けたの整数です。
注※12 UNIX64の場合,データ型がlongおよびunsigned longで,割り当てられる記憶域のサイズが8バイトのときに指定できます。
注※13 10~18けたの整数です。
注※14 割り当てられる記憶域のサイズが8バイトの場合,指定できます。
注※15 Solaris(SPARC)の場合,値渡し(BY VALUE)引数および返却項目のとき,C言語のlong long型またはunsigned long long型の変数と値の受け渡しはできません。
注※16 符号修飾子を省略したとき,unsigned charと解釈するCコンパイラを使用する場合,明示的にsigned charと書くか,または適切なCコンパイラのオプションを指定してsigned charと解釈されるようにする必要があります。

(3) 引数の受け渡し

CプログラムからCOBOLプログラムへ引数を渡す方法を,次に示します。

(a) 引数をポインタ型で受け取る
Cプログラム

int SAMPLE2(int *,char *);
   :
int SAMPLE1(....)
{
int  cnt;
char  str[80];
   :
 SAMPLE2(&cnt,str);
   :
 return(0);
}

COBOLプログラム

      IDENTIFICATION DIVISION.
      PROGRAM-ID. SAMPLE2.
          :
      LINKAGE SECTION.
      01 CNT PIC S9(9) USAGE COMP.
      01 STR PIC X(80).
           
      PROCEDURE DIVISION USING BY REFERENCE CNT STR.
          :

(b) 引数を値渡しで受け取る
Cプログラム

int  SAMPLE2(int,char);
int  SAMPLE1(....)
{
int  cnt;
char  str;
   :
 SAMPLE2(cnt,str);
   :
 return(0);
}

COBOLプログラム

      IDENTIFICATION DIVISION.
      PROGRAM-ID. SAMPLE2.
          :
      LINKAGE SECTION.
      01 CNT PIC S9(9) USAGE COMP.
      01 STR PIC X(1).
           
      PROCEDURE DIVISION USING BY VALUE CNT STR.
          :

(4) 戻り値の受け渡し

COBOLプログラムからCプログラムへ戻り値を返す方法を,次に示します。

(a) 整数型のデータ項目を返す例
Cプログラム

extern int SAMPLE2();
   :
int main()
   {
   int rtc;
   :
   rtc = SAMPLE2();
   :
   }

COBOLプログラム

      IDENTIFICATION DIVISION.
      PROGRAM-ID. SAMPLE2.
          :
      LINKAGE SECTION.
      01 RTC PIC S9(9) USAGE COMP.
      PROCEDURE DIVISION RETURNING RTC.
          :
          MOVE 12345 TO RTC.
          EXIT PROGRAM.

(b) 構造体型のデータ項目を返す例
Cプログラム

struct tbl{ int a; char b[10];};
extern struct tbl SAMPLE2();
int main()
   {
 struct tbl rtc;
   :
   rtc = SAMPLE2();
   :
   }

COBOLプログラム

      IDENTIFICATION DIVISION.
      PROGRAM-ID. SAMPLE2.
          :
      LINKAGE SECTION.
      01 TBL.
        02 A PIC S9(9) USAGE COMP.
        02 B PIC X(10).
           
      PROCEDURE DIVISION RETURNING TBL.
          :
          EXIT PROGRAM.

注意事項
C言語の構造体の場合,要素の境界調整でパディング(領域間のギャップを埋めるために挿入される暗黙のFILLER項目)が挿入されます。そのほかに,構造体のサイズを最大の基本要素サイズの倍数に切り上げるため,パディングが挿入されることがあります。この場合,パディングは構造体の末尾に挿入されます。例えば上記の例の構造体tblの場合,要素の合計のサイズはCOBOLの集団項目TBLと同じ14バイトですが,構造体のサイズを4バイト(最大の基本要素のサイズ)の倍数の16バイトにするために,2バイトのパディングが構造体の末尾に挿入されます。このため,COBOLの集団項目TBLとはサイズが不一致になります。プラットフォームによっては,このサイズの不一致が原因で,引数や戻り値の受け渡しで異常終了や結果不正となることがあるため,次のどちらかの方法でC言語の構造体のサイズとCOBOLの集団項目のサイズを一致させる必要があります。
  • C言語の構造体のサイズをCOBOLの集団項目のサイズに合わせる方法
    構造体を詰めて配置するC言語の機能(C言語の言語仕様の#pragma packやC言語のコンパイラのコンパイラオプションで提供されている)を使って構造体tblのサイズを14バイトにします。構造体を詰めて配置するC言語の機能については,各システムのCコンパイラのリファレンスを参照してください。
  • COBOLの集団項目のサイズをC言語の構造体のサイズに合わせる方法
    COBOLの集団項目TBLのサイズを16バイトにするために,COBOLの集団項目TBLの末尾に次の2バイト分のFILLER項目を追加してください。

  02 FILLER PIC X(2).