Compaq COBOL
User Manual


Previous Contents Index

12.7 Calling Non-COBOL Programs from Compaq COBOL

Because the Compaq COBOL compiler is part of a common language environment, a Compaq COBOL program can call a procedure written in another language available in this environment. This communication among high-level languages exists because these languages adhere to the OpenVMS Calling Standard or the Tru64 UNIX Calling Standard for Alpha Systems, as applicable, when generating a call to a procedure. Section 13.2 briefly describes the OpenVMS calling standard.

On OpenVMS Alpha, for more information, refer to the material on calling system routines in the OpenVMS Programming Concepts Manual, the OpenVMS RTL Library (LIB$) Manual, and the OpenVMS System Services Reference Manual. <>

12.7.1 Calling a Fortran Program

Calling a procedure written in Fortran allows you to take advantage of features of that language. Example 12-13 demonstrates how to call a non-COBOL program in the run unit.

Example 12-13 Calling a Fortran Program from a COBOL Program

IDENTIFICATION DIVISION. 
PROGRAM-ID.   GETROOT. 
**************************************************** 
* This program accepts a value from the terminal,  * 
* calls the Fortran subroutine SQROOT, and passes  * 
* the value as a character string. Program         * 
* SQROOT returns the square root of the value.     * 
**************************************************** 
DATA DIVISION. 
WORKING-STORAGE SECTION. 
01  INPUT-NUMBER. 
    03  INTEGER       PIC 9(5). 
    03  DEC-POINT     PIC X(1). 
    03  DECIMAL       PIC 9(8). 
01  WORK-NUMBER. 
    03  INTEGER       PIC 9(5). 
    03  DECIMAL       PIC 9(8). 
01  WORK-NUMBER-A REDEFINES WORK-NUMBER  PIC 9(5)V9(8). 
01  DISPLAY-NUMBER    PIC ZZ,ZZ9.9999. 
PROCEDURE DIVISION. 
STARTER SECTION. 
SBEGIN. 
   MOVE SPACES TO INPUT-NUMBER. 
   DISPLAY "Enter number (with decimal point): " 
     NO ADVANCING. 
   ACCEPT INPUT-NUMBER. 
   IF INPUT-NUMBER = SPACES 
     GO TO ENDJOB. 
   CALL "SQROOT" USING BY DESCRIPTOR INPUT-NUMBER. 
   IF INPUT-NUMBER = ALL "*" 
     DISPLAY "** INVALID ARGUMENT FOR SQUARE ROOT" 
   ELSE 
     DISPLAY "The square root is: " INPUT-NUMBER 
     INSPECT INPUT-NUMBER 
       REPLACING ALL " " BY "0" 
     MOVE CORRESPONDING INPUT-NUMBER TO WORK-NUMBER 
     WORK-NUMBER-A TO DISPLAY-NUMBER 
     DISPLAY DISPLAY-NUMBER. 
   GO TO SBEGIN. 
ENDJOB. 
   STOP RUN. 

Example 12-14 shows the Fortran program SQROOT called by the program in Example 12-13 and sample output from the programs' execution.

The SQROOT subroutine accepts a 14-character string and decodes it into a real variable (DECODE is analogous to an internal READ). It then calls the SQRT function in the statement that encodes the result into the 14-character argument.

Example 12-14 Fortran Subroutine SQROOT

      SUBROUTINE SQROOT(ARG) 
      CHARACTER*14 ARG 
      DECODE(14,10,ARG,ERR=20)VAL 
10    FORMAT(F12.6) 
      IF(VAL.LT.0.)GO TO 20 
      ENCODE(14,10,ARG)SQRT(VAL) 
999   RETURN 
20    ARG='**************' 
      GO TO 999 
      END 

Sample Run of GETROOT (OpenVMS)


$ RUN GETROOT [Return]
Enter number (with decimal point): 25. [Return]
The square root is:     5.000000 
     5.0000 
Enter number (with decimal point): )HELLO [Return]
** INVALID ARGUMENT FOR SQUARE ROOT 
Enter number (with decimal point): 1000000. [Return]
The square root is:  1000.000000 
1,000.0000 
Enter number (with decimal point): 2. [Return]
The square root is:     1.414214 
     1.4142 
Enter number (with decimal point): [Return]
$                                                   <>   

12.7.2 Calling a BASIC Program

The rich, yet easily accessed features of BASIC make that language a natural environment for development of short routines to be called from COBOL. Example 12-15 shows one example of a Compaq COBOL program that calls a BASIC program.

Example 12-15 Calling a BASIC Program from a COBOL Program

IDENTIFICATION DIVISION. 
PROGRAM-ID.    APPL. 
****************************************************** 
* This  COBOL program accepts credit application     * 
* information and passes this information to a BASIC * 
* program that performs a credit analysis. Notice    * 
* that the data passed to the BASIC program is in    * 
* the standard binary format.                        * 
****************************************************** 
DATA DIVISION. 
WORKING-STORAGE SECTION. 
01  APPLICATION-NUMBER   PIC 999. 
01  C-APPLICATION-NUMBER PIC 9(3) COMP. 
01  ANNUAL-SALARY        PIC 9(5). 
01  C-ANNUAL-SALARY      PIC 9(5) COMP. 
01  MORTGAGE-RENT        PIC 999. 
01  C-MORTGAGE-RENT      PIC 9(3) COMP. 
01  YEARS-EMPLOYED       PIC 99. 
01  C-YEARS-EMPLOYED     PIC 9(2) COMP. 
01  YEARS-AT-ADDRESS     PIC 99. 
01  C-YEARS-AT-ADDRESS   PIC 9(2) COMP. 
PROCEDURE DIVISION. 
010-BEGIN. 
    DISPLAY "Enter 3 digit application number". 
    ACCEPT APPLICATION-NUMBER. 
    IF APPLICATION-NUMBER = 999 
    DISPLAY "All applicants processed" STOP RUN. 
    MOVE APPLICATION-NUMBER TO C-APPLICATION-NUMBER. 
    DISPLAY "Enter 5 digit annual salary". 
    ACCEPT ANNUAL-SALARY. 
    MOVE ANNUAL-SALARY TO C-ANNUAL-SALARY. 
    DISPLAY "Enter 3 digit mortgage/rent". 
    ACCEPT MORTGAGE-RENT. 
    MOVE MORTGAGE-RENT TO C-MORTGAGE-RENT. 
    DISPLAY "Enter 2 digit years employed by current employer". 
    ACCEPT YEARS-EMPLOYED. 
    MOVE YEARS-EMPLOYED TO C-YEARS-EMPLOYED. 
    DISPLAY "Enter 2 digit years at present address". 
    ACCEPT YEARS-AT-ADDRESS. 
    MOVE YEARS-AT-ADDRESS TO C-YEARS-AT-ADDRESS. 
    CALL "APP" USING BY REFERENCE C-APPLICATION-NUMBER 
    C-ANNUAL-SALARY C-MORTGAGE-RENT 
    C-YEARS-EMPLOYED C-YEARS-AT-ADDRESS. 
    GO TO 010-BEGIN. 
Example 12_16 shows the BASIC program APP called in Example 12-15, and sample output from the program's execution.

Example 12-16 BASIC Program "APP" and Output Data

10 SUB APP (A%,B%,C%,D%,E%) 
40 IF A% = 999 THEN 999 
50 IF B% => 26000 THEN 800 
60 IF B% => 18000 THEN 600 
70 IF B% > 15000 THEN 500 
80 IF B% => 10000 THEN 400 
90 GO TO 700 
400 IF E% < 4 THEN 800 
410 IF D% < 2 THEN 800 
420 GO TO 800 
500 IF E% < 4 THEN 700 
510 GO TO 800 
600 LET X% = B% / 12 
650 IF C% => X%/4 THEN 670 
660 GO TO 800 
670 IF E% => 4 THEN 800 
700 PRINT TAB(1);"APPLICANT NUMBER ";A%; " REJECTED" 
710 GO TO 999 
800 PRINT TAB(1);"APPLICANT NUMBER ";A%;" ACCEPTED" 
999 SUBEND 

Sample Run of APPL


$ RUN APPL
Enter 3 digit application number
376 [Return]
Enter 5 digit annual salary
35000 [Return]
Enter 3 digit mortgage/rent
461 [Return]
Enter 2 digit years employed by current employer
03 [Return]
Enter 2 digit years at present address
05 [Return]
APPLICANT NUMBER  376  ACCEPTED 
Enter 3 digit application number
999 [Return]
All applicants processed

12.7.3 Calling a C Program

Calling a program or routine that is written in C allows you to take advantage of features of that language. Example 12-17 features a C routine that can be called from a COBOL program.

Example 12-17 has two global external variables, __Argc and **__Argv. Note that **__Argv[] has an extra level of indirection; it is a pointer to a pointer to an array.

Example 12-17 C Routine to Be Called from a COBOL Program

/* crtn - c function to test use of argc and argv in c routines 
 *   called from Compaq COBOL  */ 
 
#include "cobfunc.h" 
#include <stdio.h> 
 
extern int _ _Argc; 
extern char **_ _Argv[]; 
#define argc _ _Argc 
#define argv (*_ _Argv) 
 
void crtn() 
{ 
 int i; 
 
 i = 0; 
 for (i = 0; i < argc; i++) { 
  printf("argv[%d] = %s\n", i, argv[i]); 
 } 
}                                               

Example 12-18 is a representation of how you can call a C program from your Compaq COBOL application. In this case, the C routine crtn (in Example 12-17) is called.

Example 12-18 Calling a C Program from a COBOL Program

 
       IDENTIFICATION DIVISION. 
       PROGRAM-ID. CTEST. 
       DATA DIVISION. 
       WORKING-STORAGE SECTION. 
       . 
       . 
       . 
 
       PROCEDURE DIVISION. 
       MAIN SECTION. 
       A001-MAIN. 
       . 
       . 
       . 
           CALL "crtn". 
           EXIT PROGRAM. 
       END PROGRAM CTEST. 

For information on handling LIB$INITIALIZE when calling a C program, see Appendix B.

12.8 Special Considerations for Interprogram Communication

Certain situations require special consideration when your programs will communicate with other programs.

12.8.1 CALL and CANCEL Arguments

The CALL verb with a data item and the CANCEL verb with either a literal or a data item are implemented by a Run-Time Library routine that finds the appropriate program.

On Tru64 UNIX, these language features are implemented using nlist . Because of this implementation, the following items will not work on stripped images (for additional information on the strip command, refer to strip(1)):

On OpenVMS, these features are implemented by depositing information in compiler generated psects. <>

12.8.2 Calling OpenVMS Alpha Shareable Images (OpenVMS)

When calling a subprogram installed as a shareable image, the program name specified in the CALL statement can be either a literal or a data-name. The same is true for the CANCEL verb. For more information on shareable images refer to Compaq COBOL online help file and the OpenVMS Linker Utility Manual. <>

12.8.3 Calling Tru64 UNIX Shareable Objects (Tru64 UNIX)

When you call a subprogram contained in a shared object, the program name specified in the CALL statement must be a literal. The CANCEL verb cannot be applied to programs in shared objects. For more information on shared objects, refer to the Tru64 UNIX programming documentation.

12.8.4 Case Sensitivity on Tru64 UNIX

One difference between Tru64 UNIX and OpenVMS Alpha is case sensitivity. From program code creation, to your application internal operations, you must maintain an awareness of this issue when you consider porting COBOL source code between the platforms.

12.8.4.1 Linker Case Sensitivity

The linker on Tru64 UNIX is case sensitive. "JOB1" is not the same routine as "job1". However, COBOL is defined as a case insensitive language: CALL "job1" should invoke a routine whose PROGRAM-ID is JOB1. This is not true of case sensitive languages, such as C. The names option flag increases the flexibility of the Compaq COBOL compiler in communicating with case sensitive languages.

The names option has three values:

The names option flag does not apply to the CANCEL verb or to the CALL verb used with a data item. These language features are meaningful only when both the calling program and the called program are Compaq COBOL programs.

12.8.4.2 Calling C Programs from Compaq COBOL on Tru64 UNIX

Because lowercase is the names option default, the names upper option is only required to call C functions whose names contain uppercase letters, as described in Table 12-2.

Table 12-2 C Routine Called by Statement: CALL" Job1"
FLAG,
option
Routine Called
-names lowercase
/names=lower
job1() {}
-names uppercase
/names=upper
JOB1() {}
-names as_is
/names=as_is
Job1() {}

For example, a Compaq COBOL program must be compiled with the names upper option to be able to call a C program named JOB1.

12.8.4.3 Calling COBOL Programs from C on Tru64 UNIX

The lower and upper options to the -names flag and /names= option apply to the PROGRAM-ID as well as to the literals used with CALL literal. This makes it possible for C programs to call Compaq COBOL programs with either lowercase or uppercase names, as described in Table 12-3.

Table 12-3 C Invocation to Call COBOL PROGRAM-ID" Job2"
FLAG,
option
Routine Called
-names lowercase
/names=lower
job2();
-names uppercase
/names=upper
JOB2();
-names as_is
/names=as_is
not possible

The lower(case) and upper(case) options to the -names flag and /names= option preserve the semantics of calls among Compaq COBOL programs. However, the as_is option does not preserve these semantics. For example, the following code fragment will have different behavior if compiled with as_is.


PROGRAM ID JOB1. 
CALL "Job2." 
END-PROGRAM JOB1. 
PROGRAM ID JOB2. 
END-PROGRAM JOB2. 

With the lower(case) and upper(case) options on the -names flag and /names= option, the program JOB2 will be called by JOB1. However, with the as_is option, the linker will look to resolve a call to "Job2"---which in this case is just as different as if it were named job3, WORLD99, or any other routine name other than JOB2. <>

12.8.5 Additional Information

On OpenVMS, for more detailed information on system services and Run-Time Library routines, refer to the following manuals in the OpenVMS documentation set:

The following OpenVMS documentation mentioned in this chapter may also be of interest:

For more detailed information on programming in the Tru64 UNIX environment, refer to the following manuals in the Tru64 UNIX documentation set:

Refer to also the following:


Chapter 13
Using Compaq COBOL in the Alpha or VAX Common Language Environment

The Compaq COBOL compiler is part of the common language environment. This environment defines certain calling procedures and guidelines that allow you to call programs written in different languages or prewritten system routines from Compaq COBOL. You can call the following routine types from Compaq COBOL:

On Tru64 UNIX, your Compaq COBOL programs can also call routines written in other languages, including system services routines on Tru64 UNIX. These calls must conform to the Tru64 UNIX Calling Standard for Alpha Systems.

For information on Tru64 UNIX, refer to the Tru64 UNIX operating system documentation. Alternatively, use the man -k command to search through the man pages for topics. For example, to find all routines containing the string "curses," enter the following command:


%  man -k curses

The operating system will display information similar to the following:


 
curses (3)              - Library that controls cursor movement and windowing 
curses_intro (3)        - Introduction to the curses routines which optimizes 
                          terminal screen handling and updating 
restartterm (3)         - Restart terminal for curses application        <>   
 

13.1 Routines, Procedures, and Functions

The terms routine, procedure, and function are used throughout this chapter. A routine is a closed, ordered set of instructions that performs one or more specific tasks. Every routine has an entry point (the routine name) and optionally an argument list. Procedures and functions are specific types of routines: a procedure is a routine that does not return a value, whereas a function is a routine that returns a value by assigning that value to the function's identifier. In COBOL, routines are also referred to as subprograms and called programs.

System routines are prewritten operating system routines that perform common tasks, such as finding the square root of a number or allocating virtual memory. You can call any system routine from your program, provided that COBOL supports the data structures required to call the routine. The system routines used most often are Run-Time Library routines and system services.

For more information on system routines on OpenVMS Alpha, refer to the OpenVMS RTL Library (LIB$) Manual and the OpenVMS System Services Reference Manual. <>

13.2 The OpenVMS Calling Standard (OpenVMS)

The OpenVMS Calling Standard and OpenVMS Programming Interfaces: Calling a System Routine (an archived manual still available on the documentation CD-ROM) describe the concepts used by all OpenVMS Alpha and VAX languages for invoking routines and passing data between them. The following attributes are specified by the OpenVMS Calling Standard:

The following sections discuss these attributes in more detail. The OpenVMS Calling Standard also defines such attributes as the calling sequence, the argument data types and descriptor formats, condition handling, and stack unwinding. These attributes are discussed in detail in the OpenVMS Programming Concepts Manual.

13.2.1 Register and Stack Usage (Alpha)

The OpenVMS Alpha architecture provides 32 general purpose integer registers (R0-R31) and 32 floating-point registers (F0-F31), each 64 bits in length. The OpenVMS Programming Interfaces: Calling a System Routine defines the use of these registers, as listed in Table 13-1.

Table 13-1 OpenVMS Alpha Register Usage
Register Use
R0 Function value return register (see also F0, F1)
R1 Conventional scratch register
R2-R15 Conventional saved registers
R16-R21 Argument registers, one register per argument, additional arguments are placed on the stack
R22-R24 Conventional scratch registers
R25 Argument information (AI); contains argument count and argument type
R26 Return address (RA) register
R27 Procedure value (PV) register
R28 Volatile scratch register
R29 Frame pointer (FP)
R30 Stack pointer (SP)
R31 Read As Zero/Sink (RZ) register
PC Program counter
F0,F1 Function value return registers for floating-point values (F1 is used if floating-point data exceeds 8 bytes)
F2-F9 Conventional saved registers for floating-point values
F10-F15 Conventional scratch registers for floating-point values
F16-F21 Argument registers for floating-point values (one per argument, additional arguments are placed on the stack)
F22-F30 Conventional scratch registers
F31 Read As Zero/Sink (RZ) register

A stack is a LIFO (last-in/first-out) temporary storage area that the system allocates for every user process. The system keeps information about each routine call in the current image on the call stack. Then, each time you call a routine, the system creates a structure on the stack, defined as a stack frame and further discussed in the OpenVMS Calling Standard and the OpenVMS Programming Interfaces: Calling a System Routine.


Previous Next Contents Index