-1

I want to call a C++ function from a F77 main program. I have defined in the main program:

DOUBLE PRECISION FC34F, bf_Fc34F

and do a call like

FC34F = bf_Fc34F( temp )

The function bf_Fc34F is the C function in a *.C file and is defined as

double bf_Fc34F_( double T ){
  T="some_mathematical_expression";
  return T;
}

I am using g++/gfortran and when compiling the *.C file (g++ -c *.C) the *.o file has a trailing "_d" (for "double" I think) attached to it, which the main program does not have, and thus I am getting an "undefined reference" error.

Does anyone know how to overcome this issue?

anfho
  • 131
  • 1
  • 9
  • 1
    Does the C++ code compile successfully? Assigning a `double` variable to a string constant should prevent compiling, let alone linking. – wallyk May 12 '17 at 00:08
  • Why is there a trailing underscore for the function declaration but a different name (no underscore) is used for the function type definition? – wallyk May 12 '17 at 00:09
  • 1
    Your function is a C function. Why do you use a C++ compiler? Also, Fortran always passes parameters by pointer, so your C function must take `double *T` as the parameter. – DYZ May 12 '17 at 00:32
  • This question may be helpful: http://stackoverflow.com/questions/17845931/calling-c-function-subroutine-in-fortran-code – DYZ May 12 '17 at 00:37
  • 6
    Please show the details. The code, the compiler command, the error mesages. They are important. You need `extern "C"` in C++. You nees to treat name mangling. There are MANY similar questions here. Especially in link [tag:fortran-iso-c-binding]. – Vladimir F Героям слава May 12 '17 at 06:13
  • 1
    Related/(duplicates?) http://stackoverflow.com/questions/18491911/calling-c-from-fortran-linking-issue http://stackoverflow.com/questions/18491911/calling-c-from-fortran-linking-issue http://stackoverflow.com/questions/2495503/using-fortran-to-call-c-functions or just look to the right under **Related** or search `[c++] [fortan]` to see more examples. This is really nothing new here. – Vladimir F Героям слава May 12 '17 at 09:59
  • 1
    Fortran-c interoperability is *much* easier with modern features, especially `ISO_C_BINDING`. Are you really restricted to F77? I doubt it. – Ross May 12 '17 at 17:48

2 Answers2

5

You need to handle interoperability -- mainly name mangling -- from both Fortran and C++ sides:

  • From C++ use extern "C"
  • From Fortran define an explicit interface to the function specifying bind(C) and using the interoperable types

C++ code:

#include<iostream>
using namespace std;
extern "C" {
    double bf_Fc34F( double T ){
        T=T*T;
        cout << " from c++ - T: " << T << endl;
        return T;
    }
}

Fortran code:

program fc34f_test

    double precision FC34F

    interface
        function bf_Fc34F(T) bind(C,name="bf_Fc34F")
           use iso_c_binding
           real(C_DOUBLE) :: bf_Fc34F
           real(C_DOUBLE), value :: T
        end function
    endinterface

    FC34F = bf_Fc34F(2.d0)

    print*,"from Fortran - FC34F: ", FC34F

end program fc34f_test

To compile:

g++ -c fun.C ; gfortran -c main.f90 ; g++ fun.o main.o -o exe -lgfortran

To execute:

./exe

Franz
  • 534
  • 3
  • 8
0

Your C++ file needs to use extern "C" to disable C++ name mangling:

extern "C" {
double bf_Fc34F_( double T ){
  T="some_mathematical_expression";
  return T;
}
} // extern "C"
John Zwinck
  • 239,568
  • 38
  • 324
  • 436