![]() |
Software > OpenVMS Systems > Ask the Wizard ![]() HP OpenVMS Systemsask the wizard |
![]() |
The Question is: I'm trying to find out how to call a COBOL sub-program from a C program and I can't seem to find anything in the FAQ list and I am not having any luck with the OpenVMS software libraries. It is probable that I don't know how to get what I need. Is there some resource that you could direct me to that will provide some information and possibly some examples? Thank you, Ed Drake The Answer is : On OpenVMS, arguments are typically passed by value (the data is passed as the argument), by reference (the address of the data is passed as the argument), or by descriptor (the address of a descriptor -- a small data structure that describes the particular data -- is passed as the argument). Arguments are generally either longword (effectively extended out to a quadword on OpenVMS Alpha) or (on OpenVMS Alpha) quadword values. The usual approach to resolving this mixed-language programming problem thus involves reading through the OpenVMS Calling Standard documentation and becoming familiar with the OpenVMS debugger, and using these to acquire the associated and necessary familiarity with the OpenVMS Alpha argument passing mechanisms as they specifically apply to this particular set of arguments. You will then typically need to adjust the C program to create and pass in the various data structures expected by the COBOL program, or you will then adjust the COBOL program to accept the arguments passed by the C program. Sometimes you will need to create a "dummy" caller in the same language as the called routine, this in order to see exactly what argument passing mechanisms are expected by the called routine by default. In other words, this whole project generally involves learning how to match up the particular arguments passed from the calling routine to the called routine. A COBOL subroutine would typically expect a data structure to be passed in by reference, for instance. Be aware that C can pass a structure by value (effectively loading the whole structure into the argument list), which is exceedingly unusual (but expected) behaviour and not likely something that COBOL would expect -- in most cases, a C routine should be coded to pass a structure by reference. Attached is a rather old example program demonstrating C code calling COBOL code. Some of the product (and corporation) names have changed, but the principles remain the same. ---------------------------------------------------------------------------- Example-C,COBOL C Calling COBOL Passing Text, Integers and Floats COPYRIGHT (c) 1988, 1993 by Digital Equipment Corporation. ALL RIGHTS RESERVED. No distribution except as provided under contract. Copyright (c) Digital Equipment Corporation 1994. All rights reserved. PRODUCT: VAX C DEC C for OpenVMS AXP VAX COBOL DEC COBOL For OpenVMS AXP OP/SYS: OpenVMS VAX OpenVMS AXP SOURCE: Digital Equipment Corporation OVERVIEW: In this example, a C program will call a subprogram written in COBOL, passing various data types. *** CAUTION *** This sample program has been tested using DEC C V4.0 and VAX COBOL V5.2 on OpenVMS VAX V6.1, and DEC C V4.0 and DEC COBOL V2.0 on OpenVMS AXP V6.1 However, we cannot guarantee its effectiveness because of the possibility of error in transmitting or implementing it. It is meant to be used as a template for writing your own program, and it may require modification for use on your system. PROGRAM NOTES: This example will pass a string, short, long, f_float and d_float variables to a COBOL routine. COBOL, by default, sends and receives variables by reference. The default parameter passing mechanism for DEC C is by immediate value. C's default passing mechanism will work fine if the variables will not be modified in the called module. If the called module is going to change the contents of the variables, then you must pass the parameters by reference. You will use the C ampersand operator (&) to pass the address of the parameter. This example passes the parameters by reference because the COBOL module will be changing the values. Generally there are no special considerations around passing data back and forth between C and COBOL as long as the data types match. The only issue is around passing char arrays (strings) to/from COBOL. The data types used in this example are described as follows: C: char text[16]; COBOL: 01 mytext PIC X(4). This is ASCII text. It is important to remember that COBOL does not explicitly NULL terminate any strings. The C program would want to NULL terminate the ASCII text before it is sent to the COBOL program. If COBOL modifies the text field, it can move 'low-values' to the last byte or unused bytes of the string prior to sending it to the C program. C: int number, long number; COBOL: 01 mylong PIC 9(5) COMP to PIC 9(9) COMP. This is a long int in C terms. C: short small_number; COBOL: 01 myshort PIC 9 COMP to PIC 9(4) COMP. This is a short in C terms. C: float a; COBOL: 01 myfloat COMP-1. This is an signed numeric f_float. C: double b; COBOL: 01 mydfloat COMP-2. This is a signed numeric d_float. Note: COBOL only supports D_float and F_float. Compile/Link/Run Commands: On the VAX using DEC C: $ cc cmain $ cobol cobsub $ link cmain,cobsub $ run cmain On the VAX using VAX C: $ cc cmain $ cobol cobsub $ link cmain,cobsub,sys$input/opt sys$library:vaxcrtl/share <cntrl-z> $ run cmain On the AXP using DEC C: On OpenVMS AXP systems, representation of double variables defaults to G_FLOAT format if not overridden by another format with the /FLOAT or /G_FLOAT qualifier. $ cc/float=d_float cmain $ cobol cobsub $ link cmain,cobsub $ run cmain PROGRAM: C PROGRAM: DIGITAL EQUIPMENT CORPORATION, MAYNARD MASSACHUSETTS. ALL RIGHTS RESERVED. THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED. THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL. NO RESPONSIBILITY IS ASSUMED FOR THE USE OR RELIABILITY OF SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL EQUIPMENT CORPORATION. SUPPORT FOR THIS SOFTWARE IS NOT COVERED UNDER ANY DIGITAL SOFTWARE PRODUCT SUPPORT CONTRACT, BUT MAY BE PROVIDED UNDER THE TERMS OF THE CONSULTING AGREEMENT UNDER WHICH THIS SOFTWARE WAS DEVELOPED. */ #include <stdio.h> #include <stdlib.h> #include <string.h> extern unsigned int COBSUB ( char *, short *, long *, float *, double *); main ( int argc, char **argv ) char text[16]; short short_word = 0; long long_word = 0; float f_float = 0.0; double d_float = 0.0; unsigned int status = 0; memset ( text,0x41,sizeof ( text ) -1 ); text[16] = 0; short_word = 12; long_word = 12345; f_float = 1.23; d_float = 12345.67; printf("In the C main program.\n"); /* Call the COBOL program passing these variables */ status = COBSUB ( text, &short_word, &long_word, &f_float, &d_float ); if (!status) { printf(" Problem Calling COBSUB \n" ); exit ( 0 ); } /* Print out the variables after returning from COBSUB */ printf("String: %s\n Short: %d\n Long: %d\n F_float: %f\n D_float: %f\n", text, short_word, long_word, f_float, d_float); exit(0); COBOL PROGRAM: * COPYRIGHT (C) 1994 BY * DIGITAL EQUIPMENT CORPORATION, MAYNARD * MASSACHUSETTS. ALL RIGHTS RESERVED. * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED * ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE INCLUSION * OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER COPIES * THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER * PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED. * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. * DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS * SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL. * NO RESPONSIBILITY IS ASSUMED FOR THE USE OR RELIABILITY OF SOFTWARE * ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL EQUIPMENT CORPORATION. * SUPPORT FOR THIS SOFTWARE IS NOT COVERED UNDER ANY DIGITAL SOFTWARE * PRODUCT SUPPORT CONTRACT, BUT MAY BE PROVIDED UNDER THE TERMS OF THE * CONSULTING AGREEMENT UNDER WHICH THIS SOFTWARE WAS DEVELOPED. identification division. program-id. cobsub. data division. working-storage section. 01 rstatus pic s9(9) comp. linkage section. 01 passed-text pic x(16). 01 passed-short pic 9(4) comp. 01 passed-long pic 9(9) comp. 01 passed-ffloat comp-1. 01 passed-dfloat comp-2. procedure division using passed-text passed-short passed-long passed-ffloat passed-dfloat giving rstatus. start-here. display 'In the COBSUB program'. display 'The C program passed: '. display ' '. display 'Text: ' passed-text. display 'Short: ' passed-short with conversion. display 'Long: ' passed-long with conversion. display 'F_float: ' passed-ffloat with conversion. display 'D_float: ' passed-dfloat with conversion. display ' '. display 'Modify the variables before passing control back to C '. move all 'z' to passed-text. move low-value to passed-text(16:1). move 99 to passed-short move 98765 to passed-long move .98 to passed-ffloat move 9999.999 to passed-dfloat move 1 to rstatus. exit program. REFERENCES: "DEC COBOL User Manual", January 1994, (AA-Q2G1A-TE), Chapters 12 and 13 "DEC C User's Guide for OpenVMS Systems", May 1994, (AA-PUNIZC-TK), Chapter 3
|