呼び出しプロトタイプ

以下のプログラムでは、呼び出しプロトタイプの使い方を例示する。呼び出しプロトタイプを次のように定義したとする。

 identification division.
 program-id.  callsub is external.
 environment division.
 configuration section.
 special-names.
     call-convention 3 is some-language.
 data division.
 linkage section.
 01  x1     pic 9(4) comp-5.
 01  x2     pic xx.
 01  x3     pic 9(8).
 01  x7     pic x.
 procedure division some-language using by value     x1
                                        by reference x2
                                        by reference x3.
 entry "callsub2" using x2 delimited
                        any
                        x1.
 entry "printf" using x7 delimited
                       any repeated.
 end program callsub.

上記の呼び出しプロトタイプと同じソース ファイル内に、以下の「実際の」ソース コードが含まれているとする。

 identification division.
 program-id.  prog-1.
 data division.
 working-storage section.
 01  x1      pic 9(4) comp-5.
 01  x2.
     05      pic 9(4) comp-5.
     05      pic x(20).
 01  x3      pic 9(8).
 01  x4      pic 9(9) comp-5.
 01  x5      pic x.
 01  x6      pic x(20).
 procedure division.
 mainline.
     call "callsub" using x1 x2 x3

この場合、上記の CALL 文は以下に相当する。

                          by value x1
                          by reference x2
                          by reference x3

以下の例では、各種 CALL 文およびその結果を示す。

例 1

     call "callsub" using x1 x2

この CALL 文はエラーとなる。パラメーターの数が合わないためである。

例 2

     call other-language "callsub" using x1 x2 x3

この CALL 文はエラーとなる。呼び出し規則が間違っているためである。

例 3

     call "callsub" using by reference x1 x2 x3

この CALL 文はエラーとなる。x1 は値で渡す必要があるためである。

例 4

     call "callsub" using 99 x2 x3

この CALL 文は、以下を使用した呼び出しに等しい。

                          by value 99 size 2
                          by reference x2
                          by reference x3

例 5

     call "callsub" using x4 x2 x3

この CALL 文はエラーとなる。x4 の長さが合わないためである。

例 6

     call "callsub" using x1 x5 x3

この CALL 文はエラーとなる。x5 が小さすぎるためである。

例 7

     call "printf" using "A long %1\n" x4

この CALL 文では、x4 は ANY REPEATED がカバーするパラメーターである。

例 8

     call "callsub2" using "Hello" x2 x1

この CALL 文は以下に等しい。

     move "Hello" & x"00" to temp
     call "callsub2" using temp x2 x1

例 9

     call "callsub2" using x6 x2 x1

この CALL 文は以下に等しい。

     move x6 to temp
     move x"00" to temp (21:1)
     call "callsub2" using temp x2 x1

例 10

     call "callsub2" using x6 x2 x1 x4

この CALL 文はエラーとなる。渡すパラメーターが多すぎるためである。

呼び出しプロトタイプの使用例

COBOL アプリケーション プログラムで、COBOL アプリケーションから C の関数を呼び出すには、以下を行う必要がある。

COBOL 型定義および COBOL 呼び出しプロトタイプを使用すると、上記の過程を自動化できる。これにより、文字列を null 区切りの C の文字列に変換する処理も自動的に行われる。上記をすべて実行する例を以下に示す。

C の関数を呼ぶものとし、その関数を「my_C_function」とする。この機能を示す C コードの一部は次のとおり。

sample.c
-------------------------------------------------------------

/*** start of source module sample.c ***/

/*------------------------*/
/*  Include Header Files  */
/*------------------------*/
#include <stdio.h>
#include "sample.h"

/*-------------------*/
/*  Sample Function  */
/*-------------------*/
int my_C_function (parm_1, parm_2, parm_3)
num_type parm_1;
unsigned char *parm_2;
complex_type *parm_3;
{
    int rtn_code = 0;

    printf("  my-C_function: invoked\n");

    printf("  my-C_function: parm_1 = %d\n", parm_1);

    if (parm_2 == NULL) {
        printf("  my_C_function: parm_2 = IS NULL\n", parm_2);
        rtn_code = -1;
    } else {
        printf("  my_C_function: parm_2 = %s\n", parm_2);
    }

    if (parm_3 == NULL ) {
        printf("  my_C_function: parm_3 = IS NULL\n", parm_3);
        rtn_code = -1;
    } else {
        printf("  my_C_function: parm_3\n");
        printf("                (num1) = %d\n", parm_3->num1);
        printf("                (num2) = %d\n", parm_3->num2);
    }

    printf("    my_C_function: completed\n");
    return(rtn_code);
}

/*** end of source module sample.c ***/
-------------------------------------------------------------

この例では、C の関数に次の 3 つのパラメーターを使用する。

C の型定義および関数プロトタイプを含むヘッダー ファイルがある。内容は次のとおり。

sample.h

-------------------------------------------------------------

/*** start of source module sample.h ***/

#ifndef     SAMPLE
#define     SAMPLE

/*------------*/
/*  Typedefs  */
/*------------*/
typedef int num_type;
typedef struct {
        int num1;
        long num2;
} complex_type;

/*----------------------*/
/*  Function Prototype  */
/*----------------------*/
extern int my_C_function (
        num_type parm_1,
        unsigned char *parm_2,
        complex_type *parm_3
);
#endif      /* SAMPLE */
/*** end of source module sample.h ***/
-------------------------------------------------------------

最初のステップとして、C の型定義および関数プロトタイプを COBOL の型定義および呼び出しプロトタイプに変換する。

sample.cpy
-------------------------------------------------------------
 program-id. "c_typedefs" is external.
 77  char                   pic s9(2)  comp-5 is typedef.
 77  uns-char               pic  9(2)  comp-5 is typedef.
 77  short                  pic s9(4)  comp-5 is typedef.
 77  uns-short              pic  9(4)  comp-5 is typedef.
 77  int                    pic s9(9)  comp-5 is typedef.
 77  uns-int                pic  9(9)  comp-5 is typedef.
 77  long                   pic s9(9)  comp-5 is typedef.
 77  uns-long               pic  9(9)  comp-5 is typedef.
 77  d-l-float                         comp-2 is typedef.
 77  d-float                           comp-2 is typedef.
 77  float                             comp-1 is typedef.
 77  proc-pointer           procedure-pointer is typedef.
 77  data-pointer                     pointer is typedef.
 77  void                   pic  9(2)  comp-5 is typedef.
 01  num-type          is typedef       usage int.
 01 complex-type       is typedef.
     02 num1              usage int.
     02 num2              usage long.
 entry "my_C_function" using
         by value      int
         by reference  uns-char
         by reference  complex-type
     returning         int
     .
 end program "c-typedefs".
-------------------------------------------------------------

上記には以下も含まれる。

テキスト エディターを使用して、該当ファイルに下記の変更を加える。

上記の編集を行った結果は次のとおり。

sample.cpy
-------------------------------------------------------------
 program-id. "c_typedefs" is external.

 77  uns-char               pic x             is typedef.
 77  int                    pic s9(9)  comp-5 is typedef.
 77  long                   pic s9(9)  comp-5 is typedef.
 77  data-pointer                     pointer is typedef.

 01 num-type           is typedef       usage int.
 01 complex-type       is typedef.
     02 num1              usage int.
     02 num2              usage long.

 entry "my_C_function" using
         by value      int
         by reference  uns-char delimited
         by reference  complex-type
     returning         int
     .

 end program "c_typedefs".
-------------------------------------------------------------

my_C_function 関数を呼び出す COBOL アプリケーションの例を以下に示す。

-------------------------------------------------------------
 copy 'sample.cpy'.

 identification division.
 program-id.  prog.
 working-storage section.
 01  ws-parm-1                       usage num-type.
 01  ws-parm-2                       pic x(50)
      value "This is a PIC X string from COBOL".
 01  ws-parm-3                       usage complex-type.
 01  ws-return-code                  usage int.

 procedure division.
 main-code section.
     display "prog: started"

     move 123     to ws-parm-1
     move 1       to num1 IN ws-parm-3
     move 2       to num2 IN ws-parm -3

     display " "
     display "prog: call 'my_C_function' with ALL parameters"
     call "my_C_function" using ws-parm-1
                                ws-parm-2
                                ws-parm-3
                          returning ws-return-code
     end-call
     display "prog: 'my_C_function' return code = "
             ws-return-code

     display " "
     display "prog: call 'my_C_function' with NULL parameters"
     call "my_C_function" using 0
                                OMITTED
                                OMITTED
                          returning ws-return-code
     end-call
     display "prog: 'my_C_function' return code = "
             ws-return-code

     display " "
     display "prog: completed"
     exit program
     stop run.
-------------------------------------------------------------

上記の例では、以下のとおりコーディングされている。

上記の具体例の実行結果の出力は以下のとおり。

-------------------------------------------------------------
%prog
prog: started

prog: call 'my_C_function' with ALL parameters
      my_C_function: invoked
      my_C_function: parm_1 = 123
      my_C_function: parm_2 = This is a COBOL PIC X string 
      my_C_function: parm_3
                     (num1) = 1
                     (num2) = 2
      my_C_function: completed
prog: 'my_C_function' return code = +0000000000

prog: call 'my_C_function' with NULL parameters
      my_C_function: invoked
      my_C_function: parm_1 = 0
      my_C_function: parm_2 = IS NULL
      my_C_function: parm_3 = IS NULL
      my_C_function: completed

prog: 'my_C_function' return code = -0000000001

prog: completed
%
-------------------------------------------------------------