Previous | Contents | Index |
Example 11-9 shows DIGITAL Fortran 90 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 DIGITAL Fortran 90, 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 and user-defined C structures can be passed as arguments if the following conditions are met:
When DIGITAL Fortran 90 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, DIGITAL Fortran 90 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 DIGITAL Fortran 90 subprogram, the C program can use pointers to pass numeric data by reference.
Example 11-10 shows a DIGITAL Fortran 90 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 DIGITAL Fortran 90 pointer or target arguments from the example in Example 11-10.
Example 11-11 C Functions Receiving Pointer Arguments |
---|
/* C functions Fortran 90 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 DIGITAL Fortran 90 languages handle arrays:
Because of these two factors:
DIGITAL Fortran 90 orders arrays in column-major order. The following DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 90 */ 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 DIGITAL Fortran 90 program that calls the C function expshape_ (shown in Example 11-12).
Example 11-13 DIGITAL Fortran 90 Program That Passes an Explicit-Shape Array |
---|
! Pass an explicit-shape array from Fortran 90 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 DIGITAL Fortran 90, see
Section 11.1.5.
11.4.13 Handling Common Blocks of Data
The following notes apply to handling common blocks of data between DIGITAL Fortran 90 and C:
The following examples show how C and DIGITAL Fortran 90 code can access common blocks of data. The C code declares a global structure, calls the f_calc_ DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 function.
11.5 Calling Between Parallel HPF and Non-Parallel HPF Code
When calling between parallel HPF and non-parallel HPF code, the -wsf and -nowsf_main compile-time options are required in certain cases, and prohibited in other cases. For more detailed information, see the DIGITAL High Performance Fortran 90 HPF and PSE Manual.
DIGITAL Fortran 90 (DIGITAL Fortran) library routines consist of two groups of routines, commonly referred to by their DIGITAL UNIX reference page section:
When you use the f90 command to compile and link your program, ld automatically searches the object libraries in which the DIGITAL Fortran 90 library routines reside.
When you use
ld
instead of
f90
to link object modules, specify the appropriate DIGITAL Fortran 90
libraries with
-l
string option. The DIGITAL Fortran 90 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 DIGITAL 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 DIGITAL Fortran 90 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.
For More Information:
DIGITAL Fortran 90 on DIGITAL UNIX Systems provides a collection of 3f library routines designed to be called from DIGITAL Fortran 90.
The 3f library routines differ from the standard DIGITAL Fortran 90 intrinsic subprograms provided by DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 errors, such as ERR and IOSTAT. Use these routines to handle DIGITAL UNIX errors. |
I/O | fgetc , fputc , fseek , ftell , getc , putc | Consider using DIGITAL Fortran 90 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 DIGITAL Fortran 90 intrinsic functions INDEX and LEN. |
Random numbers | drandm , irand , irandm , rand , random , srand | Consider using the DIGITAL Fortran 90 intrinsic subroutines RANDOM_NUMBER and RANDOM_SEED. |
Return date and time | ctime , dtime , etime , fdate , gmtime , idate , itime , ltime , time | Consider using the DIGITAL Fortran 90 intrinsic subroutine DATE_AND_TIME or, if you need a subset of the information returned by DATE_AND_TIME, the intrinsic subroutines (DIGITAL 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. |
Tape I/O | tclose , topen , tread , trewin , tskipf , tstate , twrite | None. |
Virtual memory allocation | falloc , free , malloc | For arrays and pointers, consider using the standard Fortran 90 ALLOCATABLE attribute or the ALLOCATE and DEALLOCATE statements. |
Previous | Next | Contents | Index |