Previous | Contents | Index |
Example 10-4 shows a complete subroutine that uses a data structure argument to the SYS$GETJPIW system service.
Example 10-4 Subroutine Using a Data Structure Argument |
---|
! Subroutine to obtain absolute and incremental values of process parameters: ! CPU time, Buffered I/O count, Direct I/O count, Page faults. SUBROUTINE PROCESS_INFO(ABS_VALUES, INCR_VALUES) ! Declare the arguments and working storage INTEGER (KIND=4) ABS_VALUES(4), INCR_VALUES(4), LCL_VALUES(4) INTEGER (KIND=4) STATUS, I ! Declare the SYS$GETJPIW item list data structure in a structure declaration STRUCTURE /GETJPI_STR/ INTEGER (KIND=2) BUFLEN /4/, ITMCOD /0/ INTEGER (KIND=4) BUFADR, RETLEN /0/ END STRUCTURE ! Create a record with the fields defined in the structure declaration RECORD /GETJPI_STR/ LIST(5) ! Declare the structure of an I/O Status Block STRUCTURE /IOSB_STR/ INTEGER (KIND=4) STATUS, RESERVED END STRUCTURE ! Declare the I/O Status Block RECORD /IOSB_STR/ IOSB ! Assign all static values in the item list LIST(1).ITMCOD = JPI$_CPUTIM LIST(2).ITMCOD = JPI$_BUFIO LIST(3).ITMCOD = JPI$_DIRIO LIST(4).ITMCOD = JPI$_PAGEFLTS ! Assign all item fields requiring addresses LIST(1).BUFADR = %LOC(LCL_VALUES(1)) LIST(2).BUFADR = %LOC(LCL_VALUES(2)) LIST(3).BUFADR = %LOC(LCL_VALUES(3)) LIST(4).BUFADR = %LOC(LCL_VALUES(4)) STATUS = SYS$GETJPIW(,,,LIST,IOSB,,) ! Perform system service call IF (STATUS) STATUS = IOSB.STATUS ! Check completion status IF (.NOT. STATUS) CALL EXIT (STATUS) ! Assign the new values to the arguments DO I=1,4 INCR_VALUES(I) = LCL_VALUES(I) - ABS_VALUES(I) ABS_VALUES(I) = LCL_VALUES(I) END DO RETURN END SUBROUTINE PROCESS_INFO |
Example 10-5 is an example of the typical use of an I/O system service. The program invokes SYS$QIOW to enable Ctrl/C trapping. When the program runs, it prints an informational message whenever it is interrupted by a Ctrl/C, and then it continues execution.
Example 10-5 Ctrl/C Trapping Example |
---|
PROGRAM TRAPC INCLUDE '($SYSSRVNAM)' INTEGER (KIND=2) TT_CHAN COMMON TT_CHAN CHARACTER (LEN=40) LINE ! Assign the I/O channel. If unsuccessful stop; otherwise ! initialize the trap routine. ISTAT = SYS$ASSIGN ('TT',TT_CHAN,,) IF (.NOT. ISTAT) CALL LIB$STOP(%VAL(ISTAT)) CALL ENABLE_CTRLC ! Read a line of input and echo it 10 READ (5,'(A)',END=999) LINE TYPE *, 'LINE READ: ', LINE GO TO 10 999 END SUBROUTINE ENABLE_CTRLC INTEGER (KIND=2) TT_CHAN COMMON TT_CHAN EXTERNAL CTRLC_ROUT ! Include I/O symbols INCLUDE '($IODEF)' INCLUDE '($SYSSRVNAM)' ! Enable Ctrl/C trapping and specify CTRLC_ROUT ! as routine to be called when Ctrl/C occurs ISTAT = SYS$QIOW( ,%VAL(TT_CHAN), %VAL(IO$_SETMODE .OR. IO$M_CTRLCAST),& ,,,CTRLC_ROUT,,%VAL(3),,,) IF (.NOT. ISTAT) CALL LIB$STOP(%VAL(ISTAT)) RETURN END SUBROUTINE ENABLE_CTRLC SUBROUTINE CTRLC_ROUT PRINT *, 'Ctrl/C pressed' CALL ENABLE_CTRLC RETURN END SUBROUTINE CTRLC_ROUT |
For more examples of calling system services and RTL routines, see
Appendix F and the HP Fortran Web site.
10.9 Calling Between Compaq Fortran 77 and HP Fortran
On OpenVMS Alpha systems, you can call a Compaq Fortran 77 subprogram from
HP Fortran or call an HP Fortran subprogram from Compaq Fortran 77
(with very few exceptions). A Compaq Fortran 77 procedure and a
HP Fortran procedure can also perform I/O to the same unit number.
10.9.1 Argument Passing and Function Return Values
The recommended rules for passing arguments and function return values between Compaq Fortran 77 and HP Fortran procedures are as follows:
Example 10-6 and Example 10-7 show passing an array from an HP Fortran program to a Compaq Fortran 77 subroutine that prints its value.
Example 10-6 shows the HP Fortran program (file ARRAY_TO_F77.F90). It passes the same argument as a target and a pointer. In both cases, it is received by reference by the Compaq Fortran 77 subroutine as a target (regular) argument. The interface block in Example 10-6 is not needed, but does allow data type checking.
Example 10-6 HP Fortran Program Calling a Compaq Fortran 77 Subroutine |
---|
! Pass arrays to f77 routine. File: ARRAY_TO_F77.F90 ! This interface block is not required, but must agree ! with actual procedure. It can be used for type checking. INTERFACE ! Procedure interface block SUBROUTINE MEG(A) INTEGER :: A(3) END SUBROUTINE END INTERFACE INTEGER, TARGET :: X(3) INTEGER, POINTER :: XP(:) X = (/ 1,2,3 /) XP => X CALL MEG(X) ! Call f77 implicit interface subroutine twice. CALL MEG(XP) END |
Example 10-7 shows the Compaq Fortran 77 program called by the HP Fortran program (file ARRAY_F77.FOR).
Example 10-7 Compaq Fortran 77 Subroutine Called by an HP Fortran Program |
---|
! Get array argument from F90. File: ARRAY_F77.FOR SUBROUTINE MEG(A) INTEGER A(3) PRINT *,A END |
These files (shown in Example 10-6 and Example 10-7) might be compiled, linked, and run as follows:
$ FORTRAN ARRAY_TO_F77.F90 $ FORTRAN /OLD_F77 ARRAY_F77.FOR $ LINK/EXECUTABLE=ARRAY_TO_F77 ARRAY_TO_F77, ARRAY_F77 $ RUN ARRAY_TO_F77 1 2 3 1 2 3 |
In Example 10-6, because array A is not defined as a pointer in the interface block, the HP Fortran pointer variable XP is passed as target data by reference (address of the target data).
However, if the interface to the dummy argument had the POINTER attribute, the variable XP would be passed by descriptor. This descriptor would not work with the Compaq Fortran 77 program shown in Example 10-7.
To make global data available across HP Fortran and Compaq Fortran 77 procedures, use common blocks.
Common blocks are supported by both HP Fortran and Compaq Fortran 77, but modules are not supported by Compaq Fortran 77. Some suggestions about using common blocks follow:
HP Fortran and Compaq Fortran 77 share the same run-time system, so you can perform I/O to the same unit number by HP Fortran and Compaq Fortran 77 procedures. For instance, a HP Fortran main program can open the file, a Compaq Fortran 77 function can issue READ or WRITE statements to the same unit, and the HP Fortran main program can close the file.
Before creating a mixed-language program that contains procedures written in HP Fortran and C, you need to know how to:
Use the FORTRAN command to compile HP Fortran source files and CC to compile C source files. Link the object files using a LINK command.
For example, the following FORTRAN command compiles the HP Fortran main program EX1.F90 and the called C function UPEN.C:
$ FORTRAN EX1.F90 $ CC UPEN.C |
The following LINK command creates the executable program:
$ LINK EX1, UPEN |
When designing a program that will use HP Fortran and C, be aware of the following general rules and available HP Fortran capabilities:
You can use a function reference or a CALL statement to invoke a C function from an HP Fortran main or subprogram.
If a value will be returned, use a function reference:
C Function Declaration | HP Fortran Function Invocation |
---|---|
data-type calc(
argument-list)
{ ... } ; |
EXTERNAL CALC
data-type :: CALC, variable-name ... variable-name=CALC( argument-list) ... |
If no value is returned, use a void return value and a CALL statement:
C Function Declaration | HP Fortran Subroutine Invocation |
---|---|
void calc(
argument-list)
{ ... } ; |
EXTERNAL CALC
... CALL CALC( argument-list) |
A C main program or function can invoke an HP Fortran function or subroutine by using a function prototype declaration and invocation.
If a value is returned, use a FUNCTION declaration:
HP Fortran Declaration | C Invocation |
---|---|
FUNCTION CALC(
argument-list)
data-type :: CALC ... END FUNCTION CALC |
extern
data-type calc(
argument-list)
data-type variable-name; variable-name=calc( argument-list); ... |
If no value is returned, use a SUBROUTINE declaration and a void return value:
HP Fortran Declaration | C Invocation |
---|---|
SUBROUTINE CALC(
argument-list)
... END SUBROUTINE CALC |
extern void calc(
argument-list)
calc( argument-list); ... |
Both C and HP Fortran pass most function return data by value, but equivalent data types must be used. The following table lists a sample of equivalent function declarations in HP Fortran and C. See Table 10-8 for a complete list of data declarations.
C Function Declaration | HP Fortran Function Declaration |
---|---|
float rfort() |
FUNCTION RFORT()
REAL (KIND=4) :: RFORT |
double dfort() |
FUNCTION DFORT()
REAL (KIND=8) :: DFORT |
int ifort() |
FUNCTION IFORT()
INTEGER (KIND=4) :: IFORT |
Because there are no corresponding data types in C, you should avoid calling HP Fortran functions of type COMPLEX and DOUBLE COMPLEX, unless you pass a struct of two float (or double float) C values (see Section 10.10.9).
The floating-point format used in memory is determined by the /FLOAT qualifier for both the FORTRAN and CC commands. When floating-point data is passed as an argument or is globally available, the same floating-point format must be used in memory by both the C and HP Fortran parts of your program.
The HP Fortran LOGICAL data types contain a zero if the value is false and a --1 if the value is true, which works with C conditional and if statements.
HP Fortran follows the argument-passing rules described in Section 10.2.4. These rules include:
HP Fortran lets you specify the lengths of its intrinsic numeric data types with the following:
The following declarations of the integer An are equivalent (unless you specified the appropriate FORTRAN command qualifier):
INTEGER (KIND=4) :: A1 INTEGER (4) :: A2 INTEGER :: A3 INTEGER*4 :: A4 |
Character data in HP Fortran is passed and received by character descriptor. Dummy character arguments can use assumed-length for accepting character data of varying length.
On HP Fortran intrinsic data types, see Chapter 8.
Previous | Next | Contents | Index |