I am in the processes of converting a program from Fortran to C++. To maintain input compatibility, however, I am using subroutines and Fortran's namelist functionality following the instructions in this question. Since this is a legacy code, the namelist I am working on is a bit more ridiculous with 30+ variables. Everything works up until linking when I get the error:
main.cpp:(.text+0x2732): undefined reference to `readDatainMesh(double*, int*, int*, double*, char*, double*, char*, int*, int*, int*, double*, int*, int*, int*, double*, double*, double*, int*, int*, int*, int*, double*, double*, double*, double*, int*, int*, double*, int*, int*, double*, char*, double*, double*, double*, int*, double*, double*, double*, int*, int*, int*, char*, char*, double*, double*)'
I have the following input files:
readNamelists.f90:
subroutine readDatainMesh(...) &
bind(c, name='readDatainMesh')
use,intrinsic :: iso_c_binding,only:c_double,c_int,c_char
implicit none
real(kind=c_double), intent(inout) :: realVars
integer(kind=c_int), intent(inout) :: intVars
character(kind=c_char), intent(inout) :: charVars
.
.
.
namelist/datain_mesh/...
open(unit = 100, file = 'input.nam', status = 'old')
read(unit = 100, nml = datain_mesh)
close(unit = 100)
endsubroutine readDatainMesh
which I compile with gfortran -Wall -o readNamelists.o -c readNamelists.f90
. This produces warnings about unused dummy variables, but that is all.
I have a C header for the function, which I have checked against both the called function in main.cpp and the fortran implementation. It looks like:
#ifndef READNAMELISTS_H
#define READNAMELISTS_H
void readDatainMesh(...);
#endif
I call gcc -Wall -o main.o -c main.cpp
which gives no warnings. Then finally gcc -Wall -o main main.o readNamelists.o -lstdc++ -lgfortran
which throws the above error. I thought that perhaps the symbols werent matching so I ran nm
on both object files and the lines of interest are:
0000000000000000 T readDatainMesh
and
U _Z14readDatainMeshPdPiS0_S_PcS_S1_S0_S0_S0_S_S0_S0_S0_S_S_S_S0_S0_S0_S0_S_S_S_S_S0_S0_S_S0_S0_S_S1_S_S_S_S0_S_S_S_S0_S0_S0_S1_S1_S_S_
which obviously don't match. My question is how to I resolve this?