Skip to content

COBOL/C Interoperability

Calling COBOL from C

Overview of key COBOL-IT API functions

Function Behavior
#include <libcob.h> libcob.h is located in $COBOLITDIR/include directory. Required in C main program.
COB_RTD = cob_get_rtd(); COB_RTD is a macro that defines the runtime data rtd variable.
cob_init(rtd, 0, NULL); Cob_init initializes the runtime. Pass 0, NULL if there are no parameters to pass to the runtime. Otherwise, argc, argv.
cob_stop_run (rtd, return_status); Cleanup and terminate. This does not return.

Calling COBOL programs

Function Prototypes

Case 1:
The COBOL program say.cbl has two parameters described in the Linkage Section. In C, this is equivalent to a function having the following prototype:

extern int say(char *hello, char *world);

Case 2:
If you specified a PROGRAM-ID that is different from the source base name, two symbols will be generated. One of the symbols generated will use the PROGRAM-ID, and one will use the source base name. Expanding on the case above, if we change the PROGRAM-ID for say .cbl to MYSAY, as below,

       say.cbl

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MYSAY.
       ...

This would be the equivalent to a function having the following prototype:
extern int say(char *hello, char *world);
extern int MYSAY(char *hello, char *world);

Either of these functions can be called from the C program, as they both point to the same COBOL program.

Declaring a function prototype for a COBOL program with two parameters in the linkage section, and CALL'ing that COBOL program.

Function Behavior
extern int say(char *hello, char *world);
ret = say(hello, world);
Call a COBOL program say, and pass two parameters into linkage data items.

Using cob_resolve to find a COBOL program

In the absence of a function prototype, you can find a COBOL module having a specific PROGRAM-ID by CALL'ing the function cob_resolve. There is an example of this usage in the sample hello-dynamic.c below.

Function                 Behavior
say = cob_resolve(rtd, "say")
if (say == NULL) {
fprintf(stderr, "%s\n",cob_resolve_error (rtd));
exit(1);
}
ret = say(hello, world);
cob_resolve takes the module name as a string and returns a pointer to the module function. cob_resolve returns NULL if there is no module. cob_resolve_error can be called to return the error message. If the module say is found, it is called and passed two parameters.

This chapter describes how to interface C programs and routine with COBOL-IT programs, statically or dynamically.

Writing the Main Program in C

Examples follow, with cases where C programs are statically linked with COBOL programs, and cases where C programs are dynamically linked with COBOL programs.

Static linking of “C” programs with COBOL programs

The C program

       /* hello.c */
       #include <libcob.h>
       extern int say(char *hello, char *world);
       int main()
      {
       COB_RTD = cob_get_rtd();
       int ret;
       int return_status;
       char hello[7] = "Hello ";
       char world[7] = "World!";
       cob_init(rtd, 0, NULL);
       ret = say(hello, world);
       cob_stop_run (rtd, return_status);
       return ret;
      }

Compile the C program

In Linux/Unix:

>cc -c `cob-config --cflags` hello.c

In Windows:

>cobc –c hello.c

The COBOL program

Say.cbl is passed to two fields, which are described in the Linkage Section. Say.cbl DISPLAYs the two fields, and then exits.

       say.cbl

       IDENTIFICATION DIVISION.
       PROGRAM-ID. say.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       LINKAGE SECTION.
       01 HELLO PIC X(6).
       01 WORLD PIC X(6).
       PROCEDURE DIVISION USING HELLO WORLD.
       DISPLAY HELLO WORLD.
       EXIT PROGRAM.

Compile the COBOL program

In Linux/Unix and Windows:

>cobc -c -static say.cbl

In Linux/Unix:

>cobc -x -fno-main -o hello hello.o say.o

In Windows:

>cobc -x –flink-only -o hello hello.obj say.obj

Run the linked executable

In Linux/Unix:

>./hello

In Windows:

>hello

In summary

You can combine the compile and run commands above into scripts (Linux/Unix) or batch files (Windows) as follows:

Linux/Unix:

       >cc -c `cob-config --cflags` hello.c
       >cobc -c -static say.cbl
       >cobc -x -fno-main -o hello hello.o say.o
       >./hello

Windows 32, Windows 64:

       >cobc -c hello.c
       >cobc -c -static say.cbl
       >cobc -x -flink-only -o hello hello.obj say.obj
       >hello

Running hello returns the following output

       Hello World!

Dynamic linking of C programs with COBOL programs

Note

This sample contains usage of the functions cob_resolve( ) and cob_resolve_error, which can be used to locate a COBOL module/report errors. The C program is compiled to an executable, and COBOL program is compiled to a separate shared object (DLL in Windows ). COB_LIBRARY_PATH is set, and the CALL of the COBOL program is resolved dynamically.

The “C” program

       /* hello-dynamic.c */
       #include <libcob.h>
       static int (*say)(char *hello, char *world);
       int main()
      {
       /* COBOL-Runtime data */
       /* COB_RTD is a macro that define rtd variable*/
       COB_RTD = cob_get_rtd();
       int ret;
       char hello[7] = "Hello ";
       char world[7] = "World!";
       cob_init(rtd, 0, NULL);
       /* find the module with PROGRAM-ID "say". */
       say = cob_resolve(rtd, "say");
       /* if there is no such module, show error and exit */
       if (say == NULL) {
       fprintf(stderr, "%s\n", cob_resolve_error (rtd));
       exit(1);
      }
       /* call the module found and exit with the return code */
       ret = say(hello, world);
       return ret;
      }

Compile the C program

In Linux/Unix:

       >cc -c `cob-config --cflags` hello-dynamic.c
       >cobc -x -fno-main -o hello hello-dynamic.o

In Windows:

>cobc –x –flink-only –o hello hello-dynamic.c

The COBOL program

Say.cbl is passed to two fields, which are described in the Linkage Section. Say.cbl DISPLAYs the two fields, and then exits.

       say.cbl

       IDENTIFICATION DIVISION.
       PROGRAM-ID. say.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       LINKAGE SECTION.
       01 HELLO PIC X(6).
       01 WORLD PIC X(6).
       PROCEDURE DIVISION USING HELLO WORLD.
       DISPLAY HELLO WORLD.
       EXIT PROGRAM.

Compile the COBOL program

In Linux/Unix and Windows:

>cobc -m say.cbl

In Linux/Unix:

       >export COB_LIBRARY_PATH=.
       >./hello

In Windows:

       >set COB_LIBRARY_PATH=.
       >hello

Exiting COBOL, Returning to C

A COBOL main program can be written with an Exit Program statement, causing the program to return to the calling C program.

This is done by setting the exit-program-forced Compiler Configuration flag.
To cause the EXIT PROGRAM statement to return control to a calling C program, add the compiler figuration flag:

Exit-program-forced:yes

For more detail, see the explanation below:

exit-program-forced

The exit-program-forced configuration file flag changes the way that the EXIT PROGRAM statement is handled.

If set to no (default) the program is exited only if it is not the main program. If set to yes the EXIT PROGRAM verb always exits the current program.

In summary

You can combine the compile and run commands above into scripts (Linux/Unix) or batch files (Windows) as follows:

Linux/Unix:

       >cc -c `cob-config --cflags` hello-dynamic.c
       >cobc -x -o hello hello-dynamic.o
       >cobc -m say.cbl
       >export COB_LIBRARY_PATH=.
       >./hello

Windows 32, Windows 64:

       >cobc -x -flink-only -o hello hello-dynamic.c
       >cobc -m say.cbl
       >set COB_LIBRARY_PATH=.
       >hello

Running hello returns the following output

       Hello World!

Note

If the COBOL program say.cbl has not been compiled or if COB_LIBRARY_PATH is not set correctly, then running hello will produce the output:

       Cannot find module 'say'

Back to top