The FORTRAN-Pascal Interface |
8 |
![]() |
Compiler Mixed-Language Programs
When you compile with the -v (verbose) option, the Pascal driver brings in the runtime libraries for the main module.
hostname% pc -c my_pascal.p hostname% f77 my_pascal.o my_fortran.f -lpfc -lpc Sampmain.f: MAIN: |
The -c option to pc produces an unlinked object file.
hostname% f77 -c my_fortran.f hostname% pc my_fortran.o my_pascal.p -lpfc -lF77 my_fortran.f: MAIN: |
You can omit the libraries if the foreign language module does not interact with the runtime environment, that is, it does no I/O, memory allocation, and so on. However, there is no overhead to linking to an unused library; therefore, always link in the appropriate runtime libraries, even if you think you may not need them.
Compatibility of Types for FORTRAN and Pascal
Table 8-1 lists the default sizes and alignments of compatible types for FORTRAN and Pascal.
Table 8-2 lists the default sizes and alignments of compatible types for FORTRAN and Pascal with the -xl option:
Pascal Type |
FORTRAN Type |
Size (Bytes) |
Alignment (Bytes) |
real |
real |
4 |
4 |
integer |
integer*2 |
2 |
2 |
Precautions with Compatible Types
This section describes the precautions you must take when working with character strings and array indexes. Character Strings
There are some precautions to take with character strings regarding the null byte, passing by value, and static storage:
The commands to compile and execute Samp.p and Sampmain.f
|
hostname% pc -c Samp.p hostname% f77 Samp.o Sampmain.f -lpfc -lpc Sampmain.f: MAIN: hostname% a.out 9 9.9 |
Variable Parameters
Pascal passes all var parameters by reference, FORTRAN's default. Simple Types without the -xl Option
With var parameters, simple types match.
The commands to compile and execute SimVar.p and SimVarmain.f
|
hostname% pc -c SimVar.p hostname% f77 SimVar.o SimVarmain.f -lpfc -lpc SimVarmain.f: MAIN: hostname% a.out T F z 9 9.9 9 9.9 |
Simple Types with the -xl Option
When you pass the -xl option, the Pascal data type real must be paired with a FORTRAN data type real; the Pascal data type integer must be paired with a FORTRAN data type, integer*2. Strings of Characters
The FORTRAN counterpart to the Pascal alfa and string types is a character string, and the FORTRAN counterpart to the Pascal varying is a structure. By default, FORTRAN, passes all by reference:
Fixed Arrays
For a fixed array parameter, pass the same type and size by reference, as shown in the following example:
The FORTRAN main program, FixVecmain.f
|
integer Sum integer a(9) data a / 1,2,3,4,5,6,7,8,9 / call FixVec ( a, Sum ) write( *, "( I3 )") Sum stop end |
The commands to compile and execute FixVec.p and FixVecmain.f
|
hostname% pc -c FixVec.p hostname% f77 FixVec.o FixVecmain.f -lpfc -lpc hostname% a.out FixVecmain.f: MAIN: 45 |
The univ Arrays
You can pass any size array to a Pascal procedure expecting a univ array, but there is no advantage in doing so, since there is no type or size checking for separate compilations. However, if you want to use an existing Pascal procedure that has a univ array, you can do so. All univ arrays that are in, out, in out, or var parameters pass by reference.
The commands to compile and execute UniVec.p and UniVecmain.f
|
hostname% pc -c UniVec.p hostname% f77 UniVec.o UniVecmain.f -lpfc -lpc UniVecmain.f: MAIN: hostname% a.out 24 |
Conformant Arrays
For conformant arrays, with single-dimension array, pass upper and lower bounds, placed after the declared parameter list, as in:
function ip(var x:array[lb..ub:integer] of real):real; ... double precision v1(10) double precision z z = ip ( v1, %VAL(0), %VAL(9) ) ... |
Pascal passes the bounds by value, so FORTRAN must pass them by value, too.
function ip(var x,y:array[lb..ub:integer] of real):real; ... double precision v1(10), v2(10) double precision z z = ip ( v1, v2, %VAL(0), %VAL(9) ) ... |
Examples of single-dimension array and array of character conformant arrays follow. Conformant arrays are included here only because they are a relatively standard feature; there are usually more efficient and simpler ways to do that.
Example 1: Single-Dimension Array
The Pascal procedure, IntCA.p. Pascal passes the bounds by value.
|
procedure intca_(var a: array [lb..ub: integer] of integer); begin a[1] := 1; a[2] := 2 end; { intca_ } |
The FORTRAN main program, IntCAmain.f
|
integer k integer s(0:2) data s / 0, 0, 0 / call IntCA ( s, %VAL(0), %VAL(2) ) do k = 0, 2 write( *, "(I1)" ) s(k) end do stop end |
The commands to compile and execute IntCA.p and IntCAmain.f
|
hostname% pc -c IntCA.p hostname% f77 IntCA.o IntCAmain.f -lpfc -lpc IntCAmain.f: MAIN: hostname% a.out 0 1 2 |
Example 2: Array of Characters
The Pascal procedure, ChrCA.p. Pascal passes the bounds by value.
|
procedure chrca_(var a: array [lb..ub: integer] of char); begin a[0] := 'T'; a[13] := 'o' end; { chrca_ } |
The FORTRAN main program, ChrCAmain.f
|
character s*16 data s / "this is a string" / call ChrCA( s, %VAL(0), %VAL(15) ) write( *, "(A)" ) s stop end |
The commands to compile and execute ChrCA.p and CharCAmain.f
|
hostname% pc -c ChrCA.p hostname% f77 ChrCA.o ChrCAmain.f -lpfc -lpc ChrCAmain.f: MAIN: hostname% a.out This is a string |
Records and Structures
In most cases, a Pascal record describes the same objects as its FORTRAN structure equivalent, provided that the components have compatible types and are declared in the same order. The compatibility of the types depends mostly on size and alignment.
A Pascal record of an integer and a character string matches a FORTRAN structure of the same. Consider these examples:
The Pascal procedure, StruChr.p
|
type lenstr = record nbytes: integer; chrstr: array [0..25] of char end; procedure struchr_(var v: lenstr); begin v.chrstr := 'oyvay'; v.nbytes := 5 end; { struchr_ } |
The commands to compile and execute Struchr.p and StruChrmain.f
|
hostname% pc -c StruChr.p hostname% f77 StruChr.o StruChrmain.f -lpfc -lpc StruChrmain.f: MAIN: hostname% a.out s25='oyvay' |
Variant Records
FORTRAN equivalents of variant records can sometimes be constructed, although there is some variation with architecture, and sometimes you need to adjust the alignment.
The commands to compile and execute VarRec.p and VarRecmain.f without -xl
|
hostname% pc -c VarRec.p hostname% f77 VarRec.o VarRecmain.f VarRecmain.f: MAIN: hostname% a.out b |
Pascal Set Type
The Pascal set type is incompatible with FORTRAN. Pascal intset Type
The Pascal intset type is predefined as set of [0..127]. A variable of this type takes a minimum of 16 bytes of storage.
The Pascal procedure, IntSetVar.p, which has an intset of the elements [1, 3, 7, 8]
|
procedure intsetvar_(var s: intset); begin s := [1, 3, 7, 8] end; { intsetvar_ } |
Value Parameters
In general, Pascal passes value parameters on the stack. Simple Types without the -xl Option
Without the -xl option, simple types match.
Simple Types with the -xl Option
With the -xl option, match Pascal real with FORTRAN real and Pascal integer with FORTRAN integer*2. Type shortreal
Unlike C, there is no problem with passing shortreal value parameters between Pascal and FORTRAN. They can be passed exactly as in the previous example, with the Pascal shortreal type matching the FORTRAN real type. Arrays
Since FORTRAN cannot pass arrays by value, it cannot pass strings of characters, fixed arrays, or univ arrays by value. Conformant Arrays
Although Pascal generally passes all value parameters on the stack, the exception is value-conformant array parameters, which are handled by creating a copy in the caller environment and passing a pointer to the copy. In addition, the bounds of the array must be passed. See "Conformant Arrays" on page 177.
This example is the same as the one in the earlier section, except that the var prefix is deleted.
Pascal procedure, ChrCAx.p
|
procedure chrca_ ( a: array [lb..ub:integer] of char) ; begin a[0] := 'T' ; a[13] := 'o' ; end; { chrca_ } |
The FORTRAN main program, ChrCAmain.f
|
character s*16 data s / "this is a string" / call ChrCA( s, %VAL(0), %VAL(15) ) write( *, "(A)" ) s stop end |
The commands to compile and execute ChrCAx.p and ChrCAmain.f
|
hostname% pc -c ChrCAx.p hostname% f77 ChrCAx.o ChrCAmain.f -lpfc -lpc ChrCAmain.f: MAIN: hostname% a.out This is a string |
Pointers
Pointers are easy to pass, as shown in the following example:
The commands to compile and execute PastPtr.p and PassPtrmain.f
|
hostname% pc -c PassPtr.p hostname% f77 PassPtr.o PassPtrmain.f -lpfc -lpc PassPtrmain.f: MAIN passptrmain: hostname% a.out 9 9.9 |
Function Return Values
Function return values match types the same as with parameters, and they pass in much the same way. See "Procedure Calls: FORTRAN-Pascal" on page 172.
Simple Types
The simple types pass in a straightforward way, as follows:
The Pascal function, RetReal.p
|
function retreal_(var x: real): real; begin retreal_ := x + 1 end; { retreal_ } |
The FORTRAN main program, RetRealmain.f
|
double precision r, s, RetReal r = 2.0 s = RetReal( r ) write( *, "(2f4.1)") r, s stop end |
The commands to compile and execute RetReal.p and RetRealmain.f without -xl
|
hostname% pc -c RetReal.p hostname% f77 RetReal.o RetRealmain.f -lpfc -lpc RetRealmain.f: MAIN: hostname% a.out 2.0 3.0 |
Type shortreal
There is no problem with returning a shortreal function value between Pascal and FORTRAN. As in the previous example, it can be passed exactly, with the Pascal shortreal type matching the FORTRAN real type (without -xl).
Procedure Calls: Pascal-FORTRAN
This section parallels "Procedure Calls: FORTRAN-Pascal" on page 172. The comments and restrictions given in that section apply here, also.
Variable Parameters
Pascal passes all var parameters by reference, the FORTRAN default. Simple Types
Simple types pass in a straightforward manner, as follows:
The commands to compile and execute SimVar.p and SimVarmain.p
|
hostname% f77 -c SimVar.f SimVar.f: simvar: hostname% pc SimVar.o SimVarmain.p -lpfc -lF77 hostname% a.out true false z 9 9.9 9 9.9 |
Strings of Characters
The alfa and string types pass simply; varying strings are a little tricky. All pass by reference.
Character Dummy Arguments
When you call FORTRAN 77 routines with character dummy arguments from Pascal programs--that is, routines in which string arguments are specified as character*(*) in the FORTRAN source, there is no explicit analogue in Pascal.
The FORTRAN subroutine, mygrout.f
|
subroutine MyGrout(N) character*(*)N write(6,*) N return end |
The commands to compile and run this program
|
hostname% pc -g -c sun.pas hostname% f77 -g sun.o mygrout.f -lpc mygrout.f: mygrout: hostname% a.out Starting... Trio Jee Ending... |
Fixed Arrays
For a fixed-array parameter, pass the same type and size by reference:
The FORTRAN subroutine, FixVec.f
|
subroutine FixVec ( V, Sum ) integer Sum integer V(0:8) integer i Sum = 0 do 2 i = 0, 8 2 Sum = Sum + V(i) return end |
The commands to compile and execute FixVec.f and FixVecmain.p
|
hostname% f77 -c FixVec.f FixVec.f: fixvec: hostname% pc FixVec.o FixVecmain.p -lpfc -lF77 hostname% a.out 45 |
The univ Arrays
The univ arrays that are in, out, in out, or var parameters pass by reference.
The FORTRAN subroutine, UniVec.f
|
subroutine UniVec ( V, Last, Sum ) integer V(0:2), Last, Sum, i Sum = 0 do i = 0, Last Sum = Sum + V(i) end do return end |
The commands to compile and execute UniVec.f and UniVecmain.p
|
hostname% f77 -c UniVec.f UniVec.f: univec: hostname% pc UniVec.o UniVecmain.p -lpfc -lF77 hostname% a.out 24 |
Conformant Arrays
Pascal-conformant array parameters are not compatible if Pascal calls FORTRAN. Records and Structures
Records and structures pass as follows:
The FORTRAN subroutine, StruChr.f
|
subroutine StruChr ( vls ) structure /VarLenStr/ integer nbytes character a*25 end structure record /VarLenStr/ vls vls.a(1:5) = 'oyvay' vls.nbytes = 5 return end |
Variant Records
You can construct FORTRAN equivalents of variant records. There is some variation with architecture, and sometimes you need to adjust the alignment.
The commands to compile and execute VarRec.f and VarRecmain.p without -xl
|
hostname% f77 -c VarRec.f VarRec.f: varrec: hostname% pc VarRec.o VarRecmain.p -lpfc -lF77 hostname% a.out b |
Value Parameters
With external fortran on the procedure statement, Pascal passes value parameters as FORTRAN expects them. Simple Types
With external fortran, the procedure name in the procedure statement and in the call must be in lowercase, with no underscore (_).
Pointers
Pointers are easy to pass, as shown in the following example:
The commands to compile and execute PassPtr.f and PassPtrmain.p
|
hostname% f77 -c PassPtr.f PassPtr.f: passptr: hostname% pc PassPtr.o PassPtrmain.p -lpfc -lF77 hostname% a.out 9 9.9 |
Function Return Values
Function return values match types the same as with parameters, and they pass in much the same way. Simple Types
The simple types pass in a straightforward way, as in this example:
The FORTRAN function, RetReal.f
|
double precision function retreal ( x ) retreal = x + 1.0 return end |
The commands to compile and execute RetReal.f and RetRealmain.p
|
hostname% f77 -c RetReal.f RetReal.f retreal: hostname% pc RetReal.o RetRealmain.p -lpfc -lF77 hostname% a.out 2.0 3.0 |
Type shortreal
You can return a shortreal function value between Pascal and FORTRAN. Pass it exactly as in the previous example, with the Pascal shortreal type matching the FORTRAN real type (without -xl).
Routines as Parameters
If the passed procedure is a top-level procedure, write it as follows:
The FORTRAN subroutine, PassProc.f
|
subroutine PassProc ( r, s, prcdr ) real r, s external prcdr call prcdr ( r, s ) return end |
The commands to compile and execute PassProc.f and PassProcmain.p
|
hostname% f77 -c PassProc.f PassProc.f passproc hostname% pc PassProc.o PassProcmain.p -lpfc -lF77 hostname% a.out 8.0 9.0 |
If the procedure is not a top-level procedure, then you do not deal with how to pass it, because that requires allowing for the static link. A procedure or function passed as an argument is associated with a static link to its lexical parent's activation record.