Previous | Contents | Index |
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 Compaq Tru64 UNIX Calling Standard for Alpha Systems, as applicable, when generating a call to a procedure. Section 13.2 briefly describes the OpenVMS Alpha calling standard.
On OpenVMS, 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-12 demonstrates how to call a non-COBOL program in the run unit.
Example 12-12 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-13 shows the Fortran program SQROOT called by the program in Example 12-12 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-13 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] $ <> |
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-14 shows one example of a Compaq COBOL program that calls a BASIC program.
Example 12-14 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-15 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 |
$ 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 |
Calling a program or routine that is written in C allows you to take advantage of features of that language. Example 12-16 features a C routine that can be called from a COBOL program.
Example 12-16 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-16 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-17 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-16) is called.
Example 12-17 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, see strip(1)):
On OpenVMS Alpha, 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
12.8.4 Case Sensitivity on Tru64 UNIX and Windows NT
One difference between Tru64 UNIX and Windows NT, 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 and Windows NT 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 and Windows NT
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.
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 and Windows NT
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.
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:
See also the following:
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 <> |
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 Alpha Calling Standard (OpenVMS)
The OpenVMS Calling Standard and the OpenVMS Programming Interfaces: Calling a System Routine describe the concepts used by all OpenVMS Alpha 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
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.
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 |