COBOL2002 使用の手引 手引編


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

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

〈この項の構成〉

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

(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          */
    :
 }
  1. BY REFERENCE指定のCALL文で渡される値は,指定された一意名のアドレスです。

  2. ADDRESS OFで修飾した場合に渡される値は,一意名のアドレスではなく,一意名のアドレスが入っている領域のアドレスとなります。

  3. LENGTH OFで修飾したCONTENT指定では,一意名の長さが入っている領域のアドレスが渡されます。

  4. LENGTH OFで修飾したVALUE指定では,一意名の長さが値として渡されます。

  5. 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);
}