[an error occurred while processing this directive]

HP OpenVMS Systems

ask the wizard
Content starts here

Mixed-language programming?

» close window

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
 
 

answer written or last revised on ( 19-JUL-2000 )

» close window