Passing Data between C and COBOL

Passing data using record layouts.

A COBOL record layout is similar to a C structure containing arrays of characters. When the Compiler assigns a COBOL record layout, it does not take into account the alignment of binary or pointer data items, or byte ordering of binary (COMP-X) data items, required by any specific hardware platform; because of this, COBOL applications are extremely portable. However, this portability can cause problems in mixed-language applications. C structure layout is not as rigidly defined as COBOL record layout and varies quite widely from operating system to operating system. For example, the structure is six bytes long in COBOL, no matter what platform it is compiled on:

01  mystruct is typedef.
	    05  mystruct-key-1     pic x occurs 2.
	    05  mystruct-bin-1     pic x(4) comp-5.

However, with the C compilers provided on most operating systems, a straightforward representation of this record layout in C would give different results. For example, the following would result in a structure eight bytes long on most 32-bit operating systems, and 16 bytes long on most 64-bit operating systems, due to alignment padding:

struct mystruct
 {
	     char		mystruct_key_1[2];
	     long		mystruct_bin_1;
	 };

A better solution, because it is portable, is to represent the COBOL record mystruct using the C structure, as follows:

struct mystruct
 {
	     char		mystruct_key_1[2];
	     char		mystruct_bin_1[4];
	 };

To enable conversion of COBOL data records into the C data types for a mixed-language application, a C include file is supplied. This file, cbltypes.h and located in %ProgramFiles(x86)%\Micro Focus\Visual COBOL\include (Windows) or $COBDIR/include (UNIX), contains many of the basic types used in COBOL applications and in our CBL_ library routine interfaces. These types directly correspond to those types contained in the copybook cbltypes.cpy, found in %ProgramFiles(x86)%\Micro Focus\Visual COBOL\cpylib (Windows) or $COBDIR/cpylib (UNIX) by default.

Revisiting the example above, the following COBOL record layout:

01  mystruct is typedef.
     05  mystruct-key-1  cblt_x1 occurs 2. *> aka. "PIC X"
     05  mystruct-bin-1  cblt_x4_comp5.    *> aka. 
#                                       "PIC X(4) COMP-5"

can be correctly represented in C, using cbltypes.h, as:

#include "cbltypes.h"

	struct mystruct 
 {
		cbl_x1_t          mystruct_key_1[2];
		cbl_x4_comp5_t    mystruct_bin_1;
	};

The type name conventions used in cbltypes.h are intended to naturally reflect the PICTURE strings of the corresponding COBOL type definition. The basic types provided in this include file are as follows:

cbl_x1_t  cobol character position - basis for all types
  
cbl_pointer_t   Equivalent to: USAGE POINTER
cbl_ppointer_t  Equivalent to: USAGE PROCEDURE-POINTER
  
cbl_sx1_comp5_t Equivalent to: PIC s9(n) COMP-5 
                                         where n=1 or 2
cbl_sx2_comp5_t Equivalent to: PIC s9(n) COMP-5 
                                         where n=3 or 4
cbl_sx4_comp5_t Equivalent to: PIC s9(n) COMP-5 
                                         where n=7 through 9
cbl_sx8_comp5_t Equivalent to: PIC s9(18) COMP-5
  
cbl_x1_comp5_t  Equivalent to: PIC X(1) COMP-5
cbl_x2_comp5_t  Equivalent to: PIC X(2) COMP-5
cbl_x4_comp5_t  Equivalent to: PIC X(4) COMP-5
cbl_x8_comp5_t  Equivalent to: PIC X(8) COMP-5
  
cbl_x1_compx_t  Equivalent to: PIC X(1) COMP-X
cbl_x2_compx_t  Equivalent to: PIC X(2) COMP-X
cbl_x4_compx_t  Equivalent to: PIC X(4) COMP-X
cbl_x8_compx_t  Equivalent to: PIC X(8) COMP-X

Even though you can portably declare COBOL data in the C language, you still need to operate on that data in a C context. To enable you to do this, C library routines are provided. These routines enable many COBOL-based data types to be converted into a format suitable for use in the context of your C application component.