COBOL2002 使用の手引 手引編

[目次][用語][索引][前へ][次へ]

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

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

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

(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※5
英数字項目(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※4 符号なし2進項目(10〜18けた)
9(10) COMP 〜 9(18) COMP
9(10) COMP-X 〜 9(18) COMP-X
long long※4 符号付き2進項目(10〜18けた)
S9(10) COMP 〜 S9(18) COMP
float 単精度内部浮動小数点数字項目
COMP-1
double 倍精度内部浮動小数点数字項目
COMP-2
ポインタ型 アドレス名,アドレスデータ項目
ADDRESS
配列型 アドレスデータ項目
ADDRESS
構造体※3 集団項目

(凡例)
−:該当しない

注※1 UNIX32の場合です。

注※2 UNIX64の場合です。

注※3
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)の引数および返却項目の受け渡しはできません。

注※4 Solaris(SPARC)の場合,値渡し(BY VALUE)引数および返却項目のとき,C言語のlong long型またはunsigned long long型の変数と値の受け渡しはできません。

注※5 符号修飾子を省略したとき,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);
}
(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) 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  /* この引数の型はUNIX32の場合  */
                    /* UNIX64の場合は long long *  */
     )
 {
   printf("length(p)     =(%d)\n",*p_ptr_cl);   … 3.
    :
 }
 int SAMPLE5(
     int p_ptr_vl  /* この引数の型はUNIX32の場合  */
                   /* UNIX64の場合は long long    */
     )
 {
   printf("length(p)     =(%d)\n",p_ptr_vl);   … 4.
    :
 }
  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);
}