================================================================================ Note 14.0 Fortran Routines from VAXELN No replies JAWS::KAISER 203 lines 25-MAR-1985 09:20 -------------------------------------------------------------------------------- +---------------+ +-----------------+ | d i g i t a l | | uNOTE # 014 | +---------------+ +-----------------+ +----------------------------------------------------+-----------------+ | Title: Using Fortran Routines In A | Date: 16-Oct-84 | | VAXELN-Pascal Environment | | +----------------------------------------------------+-----------------+ | Originator: Herbert F. Maehner | Page 1 of 4 | +----------------------------------------------------+-----------------+ This Micronote discusses the VAXELN interface to VAX-11 Fortran. The following topics are covered are discussed: 1. The VAX-11 Procedure Calling Standard 2. Establishing a COMMON-data area between a VAXELN program and Fortran routines VAXELN Procedure Calling Standard --------------------------------- VAXELN Pascal (EPascal) does conform to the VAX Procedure Calling Standard. The standard allows for three methods of parameter passing : value, reference, and descriptor, and requires that values be no longer than a longword. EPascal does not explicitly support descriptors as parameters, and other languages may not treat conformant parameters as EPascal does, but EPascal does nothing to violate the calling standard. All routines can be described according to the conventions described in the summary of run-time library entry points [1]. There are principle differences in passing parameters in Pascal and Fortran: In Pascal, you may pass parameters as - values, e.g PROCEDURE Pass_it (What: INTEGER); i.e. the value of the parameter will be copied into the procedure's stack frame with no implications for the source variable. This is termed pass by value. or as - variable, e.g. PROCEDURE Pass_it (VAR What: INTEGER); i.e. the parameter will be referenced through its address. An assignment to the parameter within the procedure will directly affect the source variable. This is termed pass by reference. Page 2 In Fortran, you pass parameters as - values, e.g. SUBROUTINE Passit( What) INTEGER*4 What i.e. with no implications for the source. It uses a common data area to pass variables to the main program. The main difference to Pascal is, that Fortran uses pass by reference, although it is actually a value. Calling a Fortran routine with parameter passing from a Pascal environment, you have to declare the parameters as VAR parameters in Pascal ( Figure 1 and Figure 2). COMMON Data Area ---------------- As mentioned before, Fortran uses a COMMON data area to pass variables from procedures to the main part of the program. In VAX-11 Pascal the [COMMON] attribute enables the linker to establish the common data section. VAXELN- Pascal has no such attribute and wouldn't overlay data sections for common areas. To overcome this restriction you must use the [EXTERNAL] attribute in VAXELN-Pascal to declare the prospective data as externally declared and use a MACRO-32 declaration to assign the Fortran common part to the "global" data area (Figure 3). References: 1. VMS RUN TIME LIBRARY USER'S GUIDE (Summary of Run Time Library Entry Points) 2. VAXELN Encyclopedia, Procedures and Functions, 3. VMS MACRO Language Reference Manual Page 3 +--------------------------------------------------------------------+ | MODULE Fortran_TO_Pascal; | | | | { This module is a simple example on, how to use Fortran | | routines in VAXELN. } | | | | CONST | | Max = 50; | | | | TYPE | | Array_type = ARRAY[1..Max] OF INTEGER; | | | | VAR | | AA: [EXTERNAL] Array_type; | | | | PROCEDURE Valaccess (VAR What:INTEGER); EXTERNAL; | | | | FUNCTION Double_it (VAR What: INTEGER):INTEGER; EXTERNAL; | | | | PROGRAM FORTEST(INPUT,OUTPUT); | | | | VAR | | What,I,J,K: INTEGER; | | Twenty: [READONLY] INTEGER:=20; | | | | BEGIN | | WRITELN('Program start '); | | FOR I:=1 TO Max DO AA[I] := 0; { initialize array } | | Valaccess(Twenty); { call Fortran routine Valaccess } | | FOR I:=21 TO Max DO | | BEGIN | | What := I; | | AA[I] := Double_it(What); { use Fortran Function to | | END; double array value } | | | | { formated output to screen } | | | | K := 1; | | FOR I:=1 TO 10 DO | | BEGIN | | FOR J:=1 TO 5 DO | | BEGIN | | WRITE(AA[K]:4,' '); | | K := K+1 | | END; | | WRITELN; | | END; | | END; | | END; { end of module Fortran_to_Pascal } | | | +--------------------------------------------------------------------+ Figure 1 : VAXELN main program module Page 4 +--------------------------------------------------------------------+ | C | | C Fortran SUBROUTINE TO SET THE INDEXED ARRAY VALUE | | C THE MAXIMAL INDEX IS PASSED AS A PARAMETER | | C | | SUBROUTINE VALACCESS(WHAT) | | IMPLICIT INTEGER*4 (A-Z) | | C | | COMMON /XX$AA/ AA(50) | | C | | C | | DO 10 I=1,What | | AA(I) = What-I | | 10 CONTINUE | | C | | RETURN | | C | | END | | C | | C | | C | | C INTEGER FUNCTION TO DOUBLE THE VALUE PASSED AS A PARAMETER | | C | | INTEGER FUNCTION DOUBLE_IT(WHAT) | | IMPLICIT INTEGER*4 (A-Z) | | DOUBLE_IT = WHAT + WHAT | | RETURN | | C | | END | | | +--------------------------------------------------------------------+ Figure 2: External Fortran routines used +--------------------------------------------------------------------+ | ; | | ; definition file for common array AA to be accessed by Fortran | | ; subroutine VALACCESS | | ; the P-section name XX$AA must be the same as the one used in the | | ; Fortran routine | | ; | | .TITLE COMDAT | | .PSECT XX$AA,LONG,PIC,USR,OVR,REL,GBL,SHR,NOEXE,RD,WRT,NOVEC | | AA:: .LONG 50 | | .END | | | +--------------------------------------------------------------------+ Figure 3: MACRO definition module to define the common array