The following program demonstrates the use of call prototypes. Assume that you have defined the following call prototype:
 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. 
            If you had the following "real" source coded in the same source file as the previous call prototype:
 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 
            the preceding CALL statement would be equivalent to using:
                          by value x1
                          by reference x2
                          by reference x3 
            The following examples show the results of different call statements:
Example 1
call "callsub" using x1 x2
The preceding CALL statement would generate an error since the number of parameters is wrong.
Example 2
call other-language "callsub" using x1 x2 x3
The preceding CALL statement would generate an error since the call-convention is wrong.
Example 3
call "callsub" using by reference x1 x2 x3
The preceding CALL statement would generate an error since x1 should be passed by value.
Example 4
call "callsub" using 99 x2 x3
The preceding CALL statement would be equivalent to a call using:
                          by value 99 size 2
                          by reference x2
                          by reference x3 
            Example 5
call "callsub" using x4 x2 x3
The preceding CALL statement would generate an error since x4 has the wrong length.
Example 6
call "callsub" using x1 x5 x3
The preceding CALL statement would generate an error since x5 is too small.
Example 7
call "printf" using "A long %1\n" x4
In the preceding CALL statement x4 is a parameter covered by ANY REPEATED.
Example 8
call "callsub2" using "Hello" x2 x1
The preceding CALL statement is equivalent to:
     move "Hello" & x"00" to temp
     call "callsub2" using temp x2 x1 
            Example 9
call "callsub2" using x6 x2 x1
The preceding CALL statement is equivalent to:
     move x6 to temp
     move x"00" to temp (21:1)
     call "callsub2" using temp x2 x1 
            Example 10
call "callsub2" using x6 x2 x1 x4
The preceding CALL statement would generate an error as there are too many parameters being passed.
Example of Call Prototype Usage
If a COBOL application programmer wants to call a C function from within his COBOL application the following need to be done:
The use of COBOL typedefs and COBOL call prototypes may be used to automate the above process. This includes the automatic conversion of text strings into null terminated C strings. The following is an example of how all this may be done.
Suppose I have a C function that I want to call. Let us call it my_C_function. The following is a segment of C code that shows this function:
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 ***/
------------------------------------------------------------- 
            In this example we have three parameters for the C function:
There is a header file that contains the C typedef definitions and also the C function prototype. It is as follows:
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 ***/
------------------------------------------------------------- 
            The first step is to convert the C typedefs and function prototypes into COBOL typedefs and COBOL call prototypes.
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".
------------------------------------------------------------- 
            In the above we have:
The following changes should be made to this file with a text editor.
The result of the above editing is the following:
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".
------------------------------------------------------------- 
            The following is an example of the COBOL application that makes a call to the my_C_function function.
-------------------------------------------------------------
 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.
------------------------------------------------------------- 
            In the above example the following has been coded:
Typedefs and prototypes are defined as complete external programs. They are placed before real source programs in a similar way to multi-program source files.
This is required because it is not possible to just go BY VALUE 0 which would be flagged as invalid because BY REFERENCE is mandatory for that parameter. OMITTED will pass a NULL instead of a pointer to the parameter being passed to the C function.
The following is the output that results when the specific example above is 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
%
-------------------------------------------------------------