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
DISPLAY
s 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
Statically link the “C” and COBOL programs
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
DISPLAY
s 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
Dynamically link the “C” and COBOL programs
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'