Mixing Fortran and C++

When mixing Fortran and C++ in the same program, you need to invoke the C++ compiler to correctly link the final program.

Most of the information in this section applies to Fortran and languages with similar data types and naming schemes. However, to mix Fortran and C++ in the same program, you must add an extra level of indirection and pass the interlanguage calls through C wrapper functions.

Because the C++ compiler mangles the names of some C++ objects, you must use your C++ compiler's invocation command, like xlC or g++, to link the final program and include -L and -l options for the XL Fortran library directories and libraries as shown in Linking 32–bit non-SMP object files using the ld command and Linking 64-bit non-SMP object files using the ld command (in the XL Fortran Compiler Reference).

Figure 1. Main Fortran program that calls C++ (main1.f)
       program main

       integer idim,idim1

       idim = 35
       idim1= 45

       write(6,*) 'Inside Fortran calling first C function'
       call cfun(idim)
       write(6,*) 'Inside Fortran calling second C function'
       call cfun1(idim1)
       write(6,*) 'Exiting the Fortran program'
       end
Figure 2. C wrapper functions for calling C++ (cfun.C)
 #include <stdio.h>
 #include "cplus.h"

 extern "C" void cfun(int *idim){
   printf("%%%Inside C function before creating C++ Object\n");
   int i = *idim;
   junk<int>* jj= new junk<int>(10,30);
   jj->store(idim);
   jj->print();
   printf("%%%Inside C function after creating C++ Object\n");
   delete jj;
   return;
 }

 extern "C" void cfun1(int *idim1) {
   printf("%%%Inside C function cfun1 before creating C++ Object\n");
   int i = *idim1;
   temp<double> *tmp = new temp<double>(40, 50.54);
   tmp->print();
   printf("%%%Inside C function after creating C++ temp object\n");
   delete tmp;
   return;
 }
Figure 3. C++ code called from Fortran (cplus.h)
 #include <iostream.h>

 template<class T> class junk {

   private:
    int inter;
    T   templ_mem;
    T   stor_val;

   public:
    junk(int i,T j): inter(i),templ_mem(j)
                     {cout <<"***Inside C++ constructor" << endl;}

     ~junk()          {cout <<"***Inside C++ Destructor"  <<	endl;}

    void store(T *val){ stor_val = *val;}

    void print(void) {cout << inter << "\t" << templ_mem ;
                      cout <<"\t" << stor_val << endl; }};

 template<class T> class temp {

   private:
     int internal;
     T temp_var;

   public:
     temp(int i, T j): internal(i),temp_var(j)
                      {cout <<"***Inside C++ temp Constructor" <<endl;}

      ~temp()          {cout <<"***Inside C++ temp destructor"  <<endl;}

     void print(void) {cout << internal << "\t" << temp_var << endl;}};
Compiling this program, linking it with the xlC command, and running it produces the following output:
 Inside Fortran calling first C function
%Inside C function before creating C++ Object
***Inside C++ constructor
10      30      35
%Inside C function after creating C++ Object
***Inside C++ Destructor
 Inside Fortran calling second C function
%Inside C function cfun1 before creating C++ Object
***Inside C++ temp Constructor
40      50.54
%Inside C function after creating C++ temp object
***Inside C++ temp destructor
 Exiting the Fortran program


Voice your opinion on getting help information Ask IBM compiler experts a technical question in the IBM XL compilers forum Reach out to us