Microsoft KB Archive/41399

How to Pass Parameters by Reference when COBOL Calls C

PSS ID Number: Q41399 Article last modified on 04-20-1993

3.00 3.00a | 3.00 3.00a MS-DOS | OS/2

Summary: The program example below demonstrates the correct method of calling from COBOL Versions 3.0 or 3.0a to C and passing variables by reference. In the program example shown below, an integer, a long integer, a string of characters, and a value that contain a fraction are printed to the screen and then passed from COBOL to a C subroutine. The C subroutine prints the values to the screen, shows what modifications are going to be made to the COBOL values, modifies the values, and then returns to COBOL with a RETURN-CODE. The COBOL program then redisplays the values to prove that the changed values were passed back.

More Information: A COBOL integer of PIC 9(4) comp-5 is stored in the same manner as an integer in C while an integer with PIC 9(8) comp-5 is a stored like a long integer in C. Strings must either be NULL-terminated when passed to C, or the length of the string must also be passed. The program example below uses the TERMCHAR with value set to X“00” to terminate the string with a NULL (zero-value) byte. The floating point value is passed as two integer values from COBOL and converted to a floating point number in C. The first integer is the value of the number to the left of the decimal (WHOLE-PART) and the second integer is the portion to the right of the decimal (FRACT-PART). Each of the COBOL integer values are moved into a field which has a PICTURE clause with a COMP-5 format. The COMP-5 format is equivalent to the manner that C stores its integers. The following is a code example: The COBOL program below does not require any COBOL.DIR file for compiler directives since all required directives are included in the source code. COBOL Version 3.0 or 3.0a compile step: COBOL COBMAIN; Microsoft C (Version 5.1) compile step: cl /Awlf /c subname.c Link step: LINK COBMAIN minitc subname/noe,,,lcobol.lib llibce.lib; COBOL Source Code: $SET ANS85 LITLINK NO OSVS VSC2 RTNCODE-SIZE“4” DATA DIVISION. WORKING-STORAGE SECTION. 01 PASS-INT PIC 9(4) comp-5 VALUE 01234. 01 PASS-LONG PIC 9(8) COMP-5 VALUE 987654321. 01 PASS-STR. 02 STRING-P PIC X(22) VALUE “This comes from COBOL”. 02 TERMCHAR PIC XX VALUE X“00”. 01 COB-FLOAT PIC 9999v9999 VALUE 123.1417. 01 MOD-FLOAT REDEFINES COB-FLOAT. 02 WHOLE-PART PIC 9999. 02 FRACT-PART PIC 9999. 01 PASS-FLOAT. 02 PASS-WHOLE PIC 9999 comp-5. 02 PASS-FRACT PIC 9999 comp-5. PROCEDURE DIVISION. MAIN. DISPLAY “PASSING AN INT, A LONG, A STR, AND FLOAT”. DISPLAY “START COBOL WITH”. DISPLAY “integer:” PASS-INT DISPLAY “Long :” PASS-LONG DISPLAY “String:” PASS-STR DISPLAY “FLOAT :” COB-FLOAT. MOVE WHOLE-PART to PASS-WHOLE. MOVE FRACT-PART to PASS-FRACT. CALL “C_hello” USING BY REFERENCE PASS-INT PASS-LONG PASS-STR PASS-WHOLE PASS-FRACT. MOVE PASS-WHOLE to WHOLE-PART MOVE PASS-FRACT to FRACT-PART DISPLAY “BACK TO COBOL WITH”. DISPLAY “return code:” RETURN-CODE DISPLAY “integer:” PASS-INT DISPLAY “Long :” PASS-LONG DISPLAY “String :” PASS-STR DISPLAY “FLOAT:” COB-FLOAT. STOP RUN. Microsoft C Source Code: #pragma check_stack(off) #include “float.h” long hello(int a, long b, char c, int h, int l) { double f; int i; / convert the two parts of the float to a single number / f = h + (double) l /10000; printf (“from the c program ”); printf (“integer in :%dout: 54321”,a); printf(“long in: %ldout: 7654”,b); printf(“string in: %s out: this comes from C”,c); printf(“float in: %4fout: 3.14”,f); / set the value pointed to by a = 54321 / a = 54321; b = 7654; / use the string copy command to change the info i the string./ strcpy(c,“this comes from C”); / change the integer value pointed to by h – the whole part / h = 3; /* and the integer value pointed to by l – the fraction part / l = 1400; /* pass 123456789 to COBOL via the return-code */ return (123456789); }

Additional reference words: 3.00 3.00a Copyright Microsoft Corporation 1993.