Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hybrid programming of Fortran and C++: Fortran can not call C++ subroutines [duplicate]

Tags:

c++

fortran

Recently, I was working on a project where some C++ subroutines are called by Fortran scripts (A Fortran solver intends to have some data-post-processing capability which is from a lib developed in C++). The following procedures replay the error producing process. Here I use quite simple Fortran and C++ scripts for a easy and clear demonstration.

A simple Fortran main program calls a CXX subroutine: The CXX subroutine - sub1.cxx:

    #include <stdio.h>
    using namespace :: std;
    extern "C" void func_c_();
    void func_c_()
    {
         printf("%d\n", 100);
    }

The Fortran main program - sub2.f90:

    program func_fortran
          implicit none
          call func_c()
    end program func_fortran

Compile them:

    g++ -c sub1.cxx
    gfortran -o test sub2.f90 sub1.o

We get the executable - test. Up to now, there is no problem.

Then we replace the sub1.cxx by sub1.1.cxx. It looks like:

    #include <iostream>
    using namespace :: std; 
    extern "C" void func_c_();
    void func_c_()
    {
         cout << "I am a CXX." << endl;
    }

The Fortran main program is totally the same with the previous one. We did not touch it.

Now we compile the codes:

    g++ -c sub1.1.cxx
    gfortran -o test sub2.f90 sub1.1.o

We can obtain sub1.1.o. But the error messages are thrown out:

    sub1.1.o: In function `func_c_':
    sub1.1.cxx:(.text+0xa): undefined reference to `std::cout'
    sub1.1.cxx:(.text+0xf): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
    sub1.1.cxx:(.text+0x14): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
    sub1.1.cxx:(.text+0x1c): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
    sub1.1.o: In function `__static_initialization_and_destruction_0(int, int)':
    sub1.1.cxx:(.text+0x46): undefined reference to `std::ios_base::Init::Init()'
    sub1.1.cxx:(.text+0x55): undefined reference to `std::ios_base::Init::~Init()'
    collect2: error: ld returned 1 exit status

Compared with sub1.cxx, it seems some C++ standards in sub1.1.cxx e.g. std::cout can not be recognized. Any one could figure this problem out? Additionally, here I did not use the iso_c_binding from Fortran 2013. I tried this features in some other cases but it does not work either.

like image 764
Hacunamatata Avatar asked Mar 03 '23 01:03

Hacunamatata


1 Answers

You need to link the executable against the c++ standard library:

g++ -c sub1.1.cxx
gfortran -o test sub2.f90 sub1.1.o -lstdc++

With gfortran/g++ you can also use g++ to link against the fortran library:

g++ -c sub1.1.cxx
gfortran -c sub2.f90
g++ -o test sub1.o  sub2.o -lgfortran
like image 122
francesco Avatar answered Apr 05 '23 23:04

francesco