【发布时间】:2014-02-07 15:39:08
【问题描述】:
我正在将程序从 Fortran 转换为 C++。然而,为了保持输入兼容性,我按照in this question 的说明使用子例程和 Fortran 的名单功能。由于这是一个遗留代码,我正在处理的名单有点荒谬,有 30 多个变量。当我收到错误时,一切正常,直到链接:
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*)'
我有以下输入文件:
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
我用gfortran -Wall -o readNamelists.o -c readNamelists.f90 编译。这会产生有关未使用的虚拟变量的警告,但仅此而已。
我有一个函数的 C 头文件,我已经检查了 main.cpp 中被调用的函数和 fortran 实现。它看起来像:
#ifndef READNAMELISTS_H
#define READNAMELISTS_H
void readDatainMesh(...);
#endif
我打电话给gcc -Wall -o main.o -c main.cpp,它没有发出任何警告。然后最后gcc -Wall -o main main.o readNamelists.o -lstdc++ -lgfortran 抛出上述错误。我想也许符号不匹配所以我在两个目标文件上运行nm,感兴趣的行是:
0000000000000000 T readDatainMesh
和
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_
这显然不匹配。我的问题是如何解决这个问题?
【问题讨论】:
-
你有没有试过在函数声明前添加
extern "C"?问题在于修改和不同的调用约定。