Using Modules in Mixed-Language Programming

Modules are the simplest way to exchange large groups of variables with C, because Visual Fortran modules are directly accessible from Visual C/C++. The following example declares a module in Fortran, then accesses its data from C. The Fortran code:

 ! F90 Module definition
     MODULE EXAMP
        REAL A(3)
        INTEGER I1, I2
        CHARACTER(80) LINE
        TYPE MYDATA
           SEQUENCE
           INTEGER N
           CHARACTER(30) INFO
        END TYPE MYDATA
     END MODULE EXAMP

The C code:

  \* C code accessing module data *\
  extern float EXAMP_mp_A[3];
  extern int EXAMP_mp_I1, EXAMP_mp_I2;
  extern char EXAMP_mp_LINE[80];
  extern struct {
             int N;
             char INFO[30];
  } EXAMP_mp_MYDATA;

When the C++ code resides in a .cpp file (created when you select C/C++ file from the visual development environment), C++ semantics are applied to external names, often resulting in linker errors. In this case, use the extern "C" syntax (see Visual C/C++ and Visual Basic Naming Conventions):

  \* C code accessing module data in .cpp file*\
  extern "C" float EXAMP_mp_A[3];
  extern "C" int EXAMP_mp_I1, EXAMP_mp_I2;
  extern "C" char EXAMP_mp_LINE[80];
  extern "C" struct {
             int N;
             char INFO[30];
  } EXAMP_mp_MYDATA;

You can also define a module procedure in C and make that routine part of a Fortran module by using the ALIAS directive. The C code:

   // C procedure
  void pythagoras (float a, float b, float *c)
  {
      *c = (float) sqrt(a*a + b*b);
  }

Using the same example when the C++ code resides in a .cpp file, use the extern "C" syntax (see Visual C/C++ and Visual Basic Naming Conventions):

  // C procedure
  extern "C" void pythagoras (float a, float b, float *c)
  {
      *c = (float) sqrt(a*a + b*b);
  }

The Fortran code to define the module CPROC:

   ! Fortran 95/90 Module including procedure
      MODULE CPROC
         INTERFACE
            SUBROUTINE PYTHAGORAS (a, b, res)
             !DEC$ ATTRIBUTES C :: PYTHAGORAS
             !DEC$ ATTRIBUTES REFERENCE :: res
  ! res is passed by REFERENCE because its individual attribute
  ! overrides the subroutine's C attribute
               REAL a, b, res
  ! a and b have the VALUE attribute by default because
  ! the subroutine has the C attribute
            END SUBROUTINE
         END INTERFACE
      END MODULE

The Fortran code to call this routine using the module CPROC:

   ! Fortran 95/90 Module including procedure
      USE CPROC
         CALL PYTHAGORAS (3.0, 4.0, X)
         TYPE *,X
      END