以下のプログラムでは、呼び出しプロトタイプの使い方を例示する。呼び出しプロトタイプを次のように定義したとする。
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. -------------------------------------------------------------
上記の例では、以下のとおりコーディングされている。
型定義およびプロトタイプは、完全な外部プログラムとして定義されている。それらはマルチプログラムのソース ファイルと同様、実際のソース プログラムの前に置かれている。
これが必要であるのは、単に BY VALUE 0 とすると、BY REFERENCE はそのパラメーターに必須であるため、無効と見なされるためである。OMITTED を指定すると、パラメーターへのポインターの代わりに NULL が C 関数に渡される。
上記の具体例の実行結果の出力は以下のとおり。
------------------------------------------------------------- %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 % -------------------------------------------------------------