Previous | Contents | Index |
Example 11-9 shows Compaq Fortran code that passes a COMPLEX (KIND=4) value (1.0,0.0) by immediate value to subroutine foo. To pass COMPLEX arguments by value, the compiler passes the real and imaginary parts of the argument as two REAL arguments by immediate value.
Example 11-9 Calling C Functions and Passing Complex Arguments |
---|
! Using !DEC$ATTRIBUTES to pass COMPLEX argument by value to F90 or C. ! File: cv_main.f90 interface subroutine foo(cplx) !DEC$ATTRIBUTES C :: foo complex cplx end subroutine end interface complex(kind=4) c c = (1.0,0.0) call foo(c) ! pass by value end |
If subroutine foo were written in Compaq Fortran, it might look similar to the following example. In this version of subroutine foo, the COMPLEX parameter is received by immediate value. To accomplish this, the compiler accepts two REAL parameters by immediate value and stores them into the real and imaginary parts, respectively, of the COMPLEX parameter cplx.
! File: cv_sub.f90 subroutine foo(cplx) !DEC$ATTRIBUTES C :: foo complex cplx print *, 'The value of the complex number is ', cplx end subroutine |
If subroutine foo were written in C, it might look similar to the following example in which the complex number is explicitly specified as two arguments of type float:
/* File: cv_sub.c */ #include <stdio.h> typedef struct {float c1; float c2;} complex; void foo(complex c) { printf("The value of the complex number is (%f,%f)\n", c.c1, c.c2); } |
The main routine (shown in Example 11-9) might be compiled and linked to the object file created by the compilation of the Compaq Fortran subroutine and then run as follows:
% f90 -o cv cv_main.f90, cv_sub.f90 % cv The value of the complex number is (1.000000,0.0000000E+00) |
The main routine might also be compiled and linked to the object file created by the compilation of the C subroutine and then run as follows:
% cc -c cv_sub.c % f90 -o cv2 cv_main.f90 cv_sub.f90 % cv2 The value of the complex number is (1.000000,0.000000) |
User-defined derived types in Compaq Fortran and user-defined C structures can be passed as arguments if the following conditions are met:
When Compaq Fortran passes scalar numeric data with the pointer attribute, how the scalar numeric data gets passed depends on whether or not an interface block is provided:
When passing scalar numeric data without the pointer attribute, Compaq Fortran passes the actual data by reference. If the called C function declares the dummy argument for the passed data to be passed by a pointer, it accepts the actual data passed by reference (address) and handles it correctly.
Similarly, when passing scalar data from a C program to a Compaq Fortran subprogram, the C program can use pointers to pass numeric data by reference.
Example 11-10 shows a Compaq Fortran program that passes a scalar (nonarray) pointer to a C function. Variable x is a pointer to variable y.
The function call to ifunc1_ uses a procedure interface block, whereas the function call to ifunc2_ does not. Because ifunc1_ uses a procedure interface block (explicit interface) and the argument is given the pointer attribute, the pointer is passed. Without an explicit interface (ifunc2_) , the target data is passed.
Example 11-10 Calling C Functions and Passing Pointer Arguments |
---|
! Pass scalar pointer argument to C. File: scalar_pointer.f90 interface function ifunc1(a) integer, pointer :: a integer ifunc1 end function end interface integer, pointer :: x integer, target :: y y = 88 x => y print *,ifunc1(x) ! interface block visible, so pass ! pointer by reference. C expects "int **" print *,ifunc2(x) ! no interface block visible, so pass ! value of "x" by reference. C expects "int *" print *,y end |
Example 11-11 shows the C function declarations that receive the Compaq Fortran pointer or target arguments from the example in Example 11-10.
Example 11-11 C Functions Receiving Pointer Arguments |
---|
/* C functions Fortran pointers. File: scalar_pointer.c */ int ifunc1_(int **a) { printf("a=%d\n",**a); **a = 99; return 100; } int ifunc2_(int *a) { printf("a=%d\n",*a); *a = 77; return 101; } |
The files (shown in Example 11-10 and Example 11-11) might be compiled, linked, and run as follows:
% cc -c scalar_pointer.c % f90 -o scalar_pointer scalar_pointer.f90 scalar_pointer.o % scalar_pointer a=88 100 a=99 101 77 |
There are two major differences between the way the C and Compaq Fortran languages handle arrays:
Because of these two factors:
Compaq Fortran orders arrays in column-major order. The following Compaq Fortran array declaration for a 2 by 3 array creates elements ordered as y(1,1), y(2,1), y(1,2), y(2,2), y(1,3), y(2,3):
integer y(2,3) |
The Compaq Fortran declaration for a 2 by 3 array can be modified as follows to have the lowest bound 0 and not 1, resulting in elements ordered as y(0,0), y(1,0), y(0,1), y(1,1), y(0,2), y(1,2):
integer y(0:1,0:2) |
The following C array declaration for a 3 by 2 array has elements in row-major order as z[0,0], z[0,1], z[1,0], z[1,1], z[2,0], z[2,1]:
int z[3][2] |
To use C and Compaq Fortran array data:
When passing certain array arguments, if you use an explicit interface that specifies the dummy argument as an array with the POINTER attribute or an assumed-shape array, the argument is passed by array descriptor (see Section 11.1.7).
For information about performance when using multidimensional arrays, see Section 5.4.
Example 11-12 shows a C function declaration for function expshape_ , which prints the passed explicit-shape array.
Example 11-12 C Function That Receives an Explicit-Shape Array |
---|
/* Get explicit-shape arrays from Fortran */ void expshape_(int x[3][2]) { int i,j; for (i=0;i<3;i++) for (j=0;j<2;j++) printf("x[%d][%d]=%d\n",i,j,x[i][j]); } |
Example 11-13 shows a Compaq Fortran program that calls the C function expshape_ (shown in Example 11-12).
Example 11-13 Compaq Fortran Program That Passes an Explicit-Shape Array |
---|
! Pass an explicit-shape array from Fortran to C. integer :: x(2,3) x = reshape( (/(i,i=1,6)/), (/2,3/) ) call expshape(x) end |
The files (shown in Example 11-12 and Example 11-13) might be compiled, linked, and run as follows:
% cc -c exparray.c % f90 -o exparray exparray.f90 exparray.o % exparray x[0][0]=1 x[0][1]=2 x[1][0]=3 x[1][1]=4 x[2][0]=5 x[2][1]=6 |
For information on the use of array arguments with Compaq Fortran, see
Section 11.1.5.
11.4.13 Handling Common Blocks of Data
The following notes apply to handling common blocks of data between Compaq Fortran and C:
The following examples show how C and Compaq Fortran code can access common blocks of data. The C code declares a global structure, calls the f_calc_ Compaq Fortran function to set the values, and prints the values:
struct S {int j; float k;}r_; main() { f_calc_(); printf("%d %f\n", r_.j, r_.k); } |
The Compaq Fortran function then sets the data values:
subroutine f_calc() common /r/j,k real k integer j j = 356 k = 5.9 return end |
The C program then prints the structure member values 356 and 5.9 set by the Compaq Fortran function.
The previous example applies to Compaq Tru64 UNIX systems. On Compaq
Linux systems, the external names with one underscore would have two
trailing underscores.
11.5 Calling Between Parallel HPF and Non-Parallel HPF Code
When calling between parallel HPF and non-parallel HPF code (TU*X ONLY), the -wsf and -nowsf_main compile-time options are required in certain cases, and prohibited in other cases. For more detailed information, see the Compaq Parallel Software Environment documentation.
Compaq Fortran (Compaq Fortran) library routines consist of two groups of routines, commonly referred to by their Tru64 UNIX or Linux reference page section:
When you use the f90 command on Tru64 UNIX systems or the fort command on Linux systems to compile and link your program, ld automatically searches the object libraries in which the Compaq Fortran library routines reside.
When you use
ld
instead of
f90
or
fort
to link object modules, specify the appropriate Compaq Fortran
libraries with
-l
string option. The Compaq Fortran libraries are listed in
Section 2.5.1.
12.1 Reference Pages for the 3f and 3hpf Routines
As indicated in Table 12-3, additional information is available in reference pages for the 3f (Fortran) routines. Also, intro(3f) provides a list of all the 3f routines.
In addition to the summary of each routine in the Compaq Fortran Language Reference Manual, detailed information is available in reference pages for the 3hpf routines. Also, intro(3hpf) lists the 3hpf routines.
You can use the man command to view online reference page information in the following ways:
% man 3f access |
% man 3hpf intro |
% man -f access |
Certain Compaq Fortran library routines have the same names as intrinsic functions or subroutines (subprograms). You need to make sure that the correct routine or intrinsic subprogram is used:
The following 3f routines have names that match similar intrinsic subprograms:
and
idate index len |
lshift
not or |
rshift
time xor |
For portability reasons, you should consider using the intrinsic routines instead of the equivalent 3f external routine.
Compaq Fortran on Compaq Tru64 UNIX and Linux Alpha systems provides a collection of 3f library routines designed to be called from Compaq Fortran.
The 3f library routines differ from the standard Compaq Fortran intrinsic subprograms provided by Compaq Fortran and fall into two groups:
Table 12-1 lists the groups of language interface library routines.
Category | Routine Names | Standard-Conforming Alternatives |
---|---|---|
Bessel mathematical operations | besj0 , besj1 , besjn , besy0 , besy1 , besyn , dbesj0 , dbesj1 , dbesjn , dbesy0 , dbesy1 , dbesyn | None. |
Bit manipulation | and , lshift , not , or , rshift , xor | Consider using the Compaq Fortran intrinsics with the same name instead. |
Directories and files | access , chdir , chmod , fstat , flush , fsync , isatty , link , lstat , rename , stat , symlnk , ttynam , umask , unlink | None. |
Error handling | gerror , ierrno , perror | Use error-handling specifiers to handle Compaq Fortran errors, such as ERR and IOSTAT. Use these routines to handle Tru64 UNIX and Linux errors. |
I/O | fgetc , fputc , fseek , ftell , getc , putc | Consider using Compaq Fortran nonadvancing I/O instead of fgetc , fputc , getc , putc . |
Miscellaneous | index , len , lnblnk , loc , long , qsort , rindex , short , system | Instead of index and len , use the Compaq Fortran intrinsic functions INDEX and LEN. |
Random numbers | drandm , irand , irandm , rand , random , srand | Consider using the Compaq Fortran intrinsic subroutines RANDOM_NUMBER and RANDOM_SEED. |
Return date and time | ctime , dtime , etime , fdate , gmtime , idate , itime , ltime , time | Consider using the Compaq Fortran intrinsic subroutine DATE_AND_TIME or, if you need a subset of the information returned by DATE_AND_TIME, the intrinsic subroutines (Compaq extensions) DATE, IDATE, and TIME. |
Return error function | erf , derf , erfc , derfc | None. |
Return process, system, or command-line information | getarg , getcwd , getenv , getgid , getlog , getpid , getuid , iargc | None. |
Signals and processes | abort , alarm , fork , kill , signal , sleep , wait | Instead of abort , consider using the STOP statement. |
Virtual memory allocation | falloc , free , malloc | For arrays and pointers, consider using the standard Fortran 95/90 ALLOCATABLE attribute or the ALLOCATE and DEALLOCATE statements. |
Table 12-2 describes the 3f routines that provide special functions allowing Compaq Fortran and C language programs to work together.
Routine Name | Function and Comments |
---|---|
for_rtl_init_ | Allows a C main language program to use the Compaq Fortran Run-Time Library environment by initializing the environment, including associated signal handlers; see for_rtl_init_ in Table 12-3 |
for_rtl_finish_ | Allows a C main language program to terminate use of the Compaq Fortran Run-Time Library environment; see for_rtl_finish_ in Table 12-3. |
for_get_fpe | Returns information on the floating-point exception handling established for the current program unit; see for_get_fpe in Table 12-3. To use for_get_fpe from a C program, you must first call for_rtl_init_ . |
for_set_fpe | Sets the floating-point exception handling established for the current program unit; see for_set_fpe in Table 12-3. To use for_set_fpe from a C program, you must first call for_rtl_init_ . |
getfd | Returns the file descriptor associated with a unit number, after the Compaq Fortran Run-Time Library environment has opened the file; see getfd in Table 12-3. |
omp_* (TU*X ONLY) | Various OpenMP Fortran API run-time routines related to parallel processing; see omp_* in Table 12-3, also Section D.1. |
ots* | Various Compaq Fortran run-time routines related to parallel processing; see Section D.2. |
shcom_connect (TU*X ONLY) | Allows multiple processes to access common block data in a shared library (uses memory mapping); see shcom_connect(3f) . |
Previous | Next | Contents | Index |