[Next] [Previous] [Up] [Top] [Contents] [Index]

Appendix I. Programming Examples

I.1 Interfacing C and FORTRAN

The following C/FORTRAN program illustrates some of the points discussed in section 16.9. Our executable is called cfort. We assume use of the make utility and Makefiles in this example. These are described in chapter 17.

The Makefile:

SHELL=/bin/sh
cfort : cf.o fc.o ; f77 -o cfort cf.o fc.o
fc.o  : fc.f      ; f77 -c fc.f
cf.o  : cf.c      ; cc  -c cf.c

The FORTRAN routine:

      PROGRAM CFORT

*   Test C/FORTRAN mixed programming techniques

*   Place COMMON variables in order REAL*8 , REAL/INTEGER , INTEGER*16 , BYTE
      COMMON /MIXED/ DCOMM, FCOMM, ICOMM
      REAL*8       DCOMM
      REAL         FCOMM
      INTEGER      ICOMM(2)

*   Arguments used in ICF function call
      INTEGER      INTE(2)
      REAL         FLO
      CHARACTER*10 STR

*   Initialize

      DCOMM    = 1.
      FCOMM    = 2.
      ICOMM(1) = 3
      ICOMM(2) = 30
      INTE(1)  = 4
      INTE(2)  = 40
      FLO      = 5.
      STR      = 'From f77'

C   Write initial values

      WRITE (*,*) ' '
      WRITE (*,*) ' / / / From FORTRAN / / / '
      WRITE (*,*) ' DCOMM  = ', DCOMM
      WRITE (*,*) ' FCOMM  = ', FCOMM
      WRITE (*,*) ' ICOMM  = ', ICOMM
      WRITE (*,*) ' INTE   = ', INTE
      WRITE (*,*) ' FLO    = ', FLO
      WRITE (*,*) ' STR    = ', STR
      WRITE (*,*) ' '

C   Use C function icf_, which prints, changes, and reprints COMMON and 
C   Argument values

      IRET = ICF ( INTE , FLO , STR )

C   Write values after call to ICF
      WRITE (*,*) ' / / / Back in FORTRAN / / / '
      WRITE (*,*) ' DCOMM  = ', DCOMM
      WRITE (*,*) ' FCOMM  = ', FCOMM
      WRITE (*,*) ' ICOMM  = ', ICOMM
      WRITE (*,*) ' INTE   = ', INTE
      WRITE (*,*) ' FLO    = ', FLO
      WRITE (*,*) ' STR    = ', STR
      WRITE (*,*) ' IRET   = ', IRET
      WRITE (*,*) ' '

      STOP
      END

The C Routine (icf_):

           /*  Test of mixed C/FORTRAN features    */

int icf_( int* inte , float* flo , char* str , int lenstr ) {
extern struct {
    double dcomm ;
    float  fcomm ;
    int    icomm[2] ;
    } mixed_ ;

printf ( "  / / / Into C / / /\n\
  DCOMM  = %f\n\
  FCOMM  = %f\n\
  ICOMM  = %d %d\n\
  INTE   = %d %d\n\
  FLO    = %f\n\
  STR    = '%.10s'\n\
  LENSTR = %d\n\n"
  ,  mixed_.dcomm , mixed_.fcomm , mixed_.icomm[0] , mixed_.icomm[1]
  , *inte , *(inte+1) , *flo , str , lenstr ) ;

mixed_.dcomm    = 10000. ;
mixed_.fcomm    = 20000. ;
mixed_.icomm[0] = 30000  ;
mixed_.icomm[1] = 330000 ;
*inte           = 40000  ;
*(inte+1)       = 440000 ;
*flo            = 50000. ;

strcpy ( str , "Out of C" ) ;

printf ( "  / / / Out of C / / /\n\
  DCOMM  = %f\n\
  FCOMM  = %f\n\
  ICOMM  = %d %d\n\
  INTE   = %d\n\
  FLO    = %f\n\
  STR    = '%.10s'\n\n"
  ,  mixed_.dcomm , mixed_.fcomm , mixed_.icomm[0] , mixed_.icomm[1]
  , *inte , *flo , str ) ;

return ( lenstr ) ;

}

Program Execution (see section 16.10):

  / / / From FORTRAN / / /
  DCOMM  =    1.000000000000000
  FCOMM  =    2.000000
  ICOMM  =            3          30
  INTE   =            4          40
  FLO    =    5.000000
  STR    = From f77

  / / / Into C / / /
  DCOMM  = 1.000000
  FCOMM  = 2.000000
  ICOMM  = 3 30
  INTE   = 4 40
  FLO    = 5.000000
  STR    = 'From f77  '
  LENSTR = 10

  / / / Out of C / / /
  DCOMM  = 10000.000000
  FCOMM  = 20000.000000
  ICOMM  = 30000 330000
  INTE   = 40000
  FLO    = 50000.000000
  STR    = 'Out of C'

  / / / Back in FORTRAN / / /
  DCOMM  =    10000.00000000000
  FCOMM  =    20000.00
  ICOMM  =        30000      330000
  INTE   =        40000      440000
  FLO    =    50000.00
  STR    = Out of C
  IRET   =           10

UNIX at Fermilab - 10 Apr 1998

[Next] [Previous] [Up] [Top] [Contents] [Index]