next up previous 252
Next: Arguments - and Pointers to Them
Up: More on Calling C from FORTRAN
Previous: Declaration of a Function


Declaration of Arguments

Scalar arguments are declared with the macros INTEGER, REAL, DOUBLE, LOGICAL, CHARACTER and TRAIL. (Or the non-standard BYTE, WORD, UBYTE, UWORD or POINTER.) The macros that declare numeric and logical arguments take account of the fact that a FORTRAN integer variable may correspond to a C type of int on one machine, but to long int on another. They also handle the mechanism that is used to pass the arguments.

Character arguments are more complex as different computers use differing mechanisms for passing the arguments. To take account of this, for every argument that is declared using the CHARACTER (or CHARACTER_ARRAY) macro, there should be a corresponding TRAIL macro at the end of the list of dummy arguments. As mentioned in a preceding example, there should not be a comma before any TRAIL macros.

C differs from FORTRAN in that it has pointer variables. These are often used to manipulate arrays, rather than by using array subscripts. The macros that are used to declare array arguments do in fact declare them to be arrays. If programmers wish to manipulate these arrays by means of pointer arithmetic, then for maximum portability they should declare separate pointers within the C function that point to the array argument.

Array arguments are declared by one of the macros type_ARRAY. The macros that declare numeric or logical array arguments declare the arrays to be pointers to type. To enable the C function to process the array correctly, the dimensions of the array should be passed as additional arguments.

The F77 macros do not allow you to declare fixed sized dimensions for an array that is a dummy argument. Normally, it is necessary to pass the dimensions as arguments of the routine anyway, but there are circumstances where the dimensions of the array will be fixed, e.g. an array might specify a rotation in space and hence is always 3 x 3. What is gained by declaring the fixed dimensions of the array is that subscript calculations can be done on arrays of more than one dimension. Unfortunately, such declarations cannot be made portable as some FORTRAN systems pass arrays by descriptor. If you really must declare arrays with fixed dimensions, you can do so as follows:

      F77_SUBROUTINE(subname)( F77_INTEGER_TYPE array[3][3] )
      {
         ...
         elem = array[i][j]
         ...
      }

This example declares the dummy argument to be an INTEGER array of fixed size. Although the subscript calculation can be performed as the routine knows the size of the array, the sizeof operator does not return the full size of the array as the complier casts array[3][3] to *array. All things considered, it is better to have the dimensions of arrays passed as separate arguments and to do the subscript arithmetic yourself with pointers. Here is an example of initializing an array of arbitrary size and arbitrary number of dimensions.

Example - Passing an array of arbitrary size from FORTRAN to C.
FORTRAN program:
      PROGRAM ARY

      INTEGER NDIMS, DIM1, DIM2, DIM3
      PARAMETER( NDIMS = 3, DIM1 = 5, DIM2 = 10, DIM3 = 2 )

      INTEGER DIMS( NDIMS )
      INTEGER A( DIM1, DIM2, DIM3 )

      DIMS( 1 ) = DIM1
      DIMS( 2 ) = DIM2
      DIMS( 3 ) = DIM3
      CALL INIT( A, NDIMS, DIMS )

      END
C function:
      #include "f77.h"

      F77_SUBROUTINE(init)( INTEGER_ARRAY(a), INTEGER(ndims), INTEGER_ARRAY(dims) )
      {
         GENPTR_INTEGER_ARRAY(a)
         GENPTR_INTEGER(ndims)
         GENPTR_INTEGER_ARRAY(dims)

         int *ptr = &a[0];  /* ptr now points to the first element of a.  */
         int size = 1;      /* Declare and initialize size.  */
         int i;             /* A loop counter.  */

         /* Find the number of elements in a.  */

         for( i = 0; i < *ndims ; i++ )
            size = size * dims[i];

         /* Set each element of a to zero.  */

         for( i = 0 ; i < size ; i++ )
            *ptr++ = 0;
      }

In this example, each element of the array a is accessed via the pointer ptr, which is incremented each time around the last loop.



next up previous 252
Next: Arguments - and Pointers to Them
Up: More on Calling C from FORTRAN
Previous: Declaration of a Function

CNF and F77 Mixed Language Programming -- FORTRAN and C
Starlink User Note 209
P.M. Allan
A.J. Chipperfield
R.F. Warren-Smith
19 January 2000
E-mail:ussc@star.rl.ac.uk