11 Subroutines and Functions as Arguments

Macros are provided to handle subroutine and function names passed as arguments. They correspond closely to the macros for handling normal data type arguments. The following example shows how to pass the name of an INTEGER function from a C program to a FORTRAN subroutine.

Example 11 – Passing names from C to FORTRAN.
A C program which calls a FORTRAN subroutine which needs the name of an INTEGER function as an argument.
  #include "f77.h"
  
  extern F77_SUBROUTINE(tst_ifun)( INTEGER_FUNCTION(name),
                                   INTEGER(status) );
  
  extern F77_INTEGER_FUNCTION(ifun)();
  
  main(){
  DECLARE_INTEGER(status);
  
     status = 0;
  
     F77_CALL(tst_ifun)( INTEGER_FUNCTION_ARG(ifun),
                          INTEGER_ARG(&status) );
  
     printf( "Status set is: %d\n", status );
  
  }

The FORTRAN subroutine:
  *+ TST_IFUN - Call an integer function
        SUBROUTINE TST_IFUN( NAME, STATUS )
  
        INTEGER NAME
        EXTERNAL NAME
        INTEGER STATUS
  
        INTEGER I
  
        STATUS = NAME( STATUS )
  
        END

The INTEGER function:
  *+ IFUN - A very simple FORTRAN INTEGER FUNCTION
        INTEGER FUNCTION IFUN( STATUS )
  
        INTEGER STATUS
  
        IFUN = STATUS + 99
  
        END

Corresponding macros are defined for other types of function and for FORTRAN subroutines.

Now suppose in the above example the subroutine TST_IFUN was written in C to be called from FORTRAN. The code would be something like:

Example 12 – Passing names from FORTRAN to C.

  *+ TESTIFUN - Call a SUBROUTINE which requires a function name argument.
        PROGRAM TSTIFUN
  
        EXTERNAL IFUN
        INTEGER STATUS
  
        CALL TST_IFUN( IFUN, STATUS )
        PRINT *, ’STATUS is: ’, STATUS
  
        END

  #include "f77.h"
  
  F77_INTEGER_FUNCTION(ifun)();
  
  F77_SUBROUTINE(tst_ifun)(INTEGER_FUNCTION(name), INTEGER(status) ){
  
  GENPTR_INTEGER_FUNCTION(name)
  GENPTR_INTEGER(status)
  
  *status = F77_EXTERNAL_NAME(name)( INTEGER_ARG(status) );