This sample describe how compile mixed COBOL and C program into a single shared library, and used by C program.
1. HELLOCBL.cbl: provide a COBOL function
2. HELLOCPP.c : provide a C function
3. mypgm.cc: the major executable file
1 and 2 is compiled into a shared library libmylib.so
COBOL-IT compiler is used.
HELLOCBL.cbl
IDENTIFICATION DIVISION. PROGRAM-ID. HELLOCBL. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. DATA DIVISION. WORKING-STORAGE SECTION. 01 ARG PIC X(50) VALUE SPACES. LINKAGE SECTION. 01 PARM-SIZE PIC S9(8) COMP-5. 01 PARM-DATA PIC X(256). PROCEDURE DIVISION USING PARM-SIZE PARM-DATA. DISPLAY "HELLOCBL PARM-SIZE=[" PARM-SIZE "]". DISPLAY "HELLOCBL PARM-DATA=[" PARM-DATA(1:PARM-SIZE) "]". MOVE 2 TO RETURN-CODE. GOBACK. * STOP RUN.
HELLOCPP.c
//extern "C" int HELLOCPP(int i, char * buffer) { printf("HELLOCPP PARM-SIZE=[%d]\n", i); printf("HELLOCPP PARM-DATA=[%s]\n", buffer); return 1; }
mypgm.cpp
#include <string.h> #include <dlfcn.h> #include <libcob.h> typedef int (* func_t)(int, char *); void * loadHandle(const char * library) { void * handle = dlopen(library, RTLD_LAZY | RTLD_GLOBAL); char * errmsg = dlerror(); if (errmsg != NULL) { printf("Cannot load shared library: [%s]: [%s]", library, errmsg); return NULL; } if (handle == NULL) { printf("Cannot load shared library: [%s]", library); return NULL; } return handle; } func_t loadFunction(void * handle, const char * name) { func_t func = (func_t) dlsym(handle, name); if (func == 0) { printf("Cannot get dlsym: [%s]", name); return NULL; } return func; } void callcppfunc(void * handle) { func_t funcpp = loadFunction(handle, "HELLOCPP"); if (funcpp != NULL) { int ret = funcpp(5, "1234567890"); printf("HELLOCPP return %d\n", ret); } } void callcblfunc(int argc, char * argv[]) { cit_runtime_t * rtd = cob_get_rtd(); cob_init(rtd, argc, argv); int size = 5; char buffer[] = { "1234567890" }; void * cobargv[3]; cobargv[0] = (void *)&size; cobargv[1] = (void *)buffer; cobargv[2] = NULL; int ret = cobcall("HELLOCBL", 2, cobargv); printf("HELLOCBL return %d\n", ret); cob_rtd_tidy(rtd); } int main(int argc, char *argv[]) { const char * library = "libmylib.so"; void * handle = loadHandle(library); if (handle != NULL) { callcppfunc(handle); callcblfunc(argc, argv); } return 0; }
makefile
PROGRAM=mypgm LIBRARY=libmylib.so all: $(PROGRAM) $(LIBRARY) mypgm: mypgm.cpp g++ $< -g -o $@ -I$(COBDIR)/include -L$(COBDIR)/lib -lcobit -ldl $(LIBRARY): HELLOCBL.cbl HELLOCPP.c cobc -fno-C-cmd-line -Wlinkage -b -g -v -fixed $^ -o $(@F) -std=mf -fmf-gnt -constant "UPPER-CALL=1" clean: -rm -rf c *.lst *.lis *.int *.idy $(LIBRARY) $(PROGRAM)
Execution
$ make $ ./mypgm HELLOCPP PARM-SIZE=[5] HELLOCPP PARM-DATA=[1234567890] HELLOCPP return 1 HELLOCBL PARM-SIZE=[+0000000005] HELLOCBL PARM-DATA=[12345] HELLOCBL return 2
the end