gpt4 book ai didi

c++ - 具有 C 接口(interface)的 Fortran 函数在尝试相互调用时会导致 undefined reference ,为什么?

转载 作者:行者123 更新时间:2023-11-30 01:55:03 24 4
gpt4 key购买 nike

我有一个旧的 Fortran 代码,出于各种原因,我正在修改它以提供使用 C++ 的功能。

在此代码中有两个函数,CALC 和 CALC2。这些函数需要从 C++ 中调用,并且它们相互调用。

CALC 的草图:

SUBROUTINE CALC(W,NW,DW,IDMX,JUMP,POINT) bind(C, name="CALC")
use iso_c_binding
C Some statements
IF (LO(36)) CALL CALC2(W,NW,DW,IDMX, .TRUE., 14)
C More statements
END

CALC2 的草图:

SUBROUTINE CALC2(W,NW,DW,IDMX,JUMP,POINT) bind(C, name="CALC2")
use iso_c_binding
C Some statements
IF (LO(222)) CALL CALC(W,NW,DW,IDMX, .TRUE., 2)
C More statements
END

我当前的 main.cpp:

extern "C" {
void CALC(double *w, double *nw, double *dw, int *idmx, int* jump, int* point);
void CALC2(double *w, double *nw, double *dw, int *idmx, int* jump, int* point);
}

int main()
{
int length = 600000;
int jump = 0;
int point = 0;
double *w = new double[length];
CALC( w, w, w, &length, &jump, &point);
CALC2( w, w, w, &length, &jump, &point);
return 0;
}

运行我的 make 文件一切都正确编译,但是到了链接阶段我得到了这个:

g++ (big list of .o files) -lgfortran -o ecis
b1_calc.o: In function `CALC':
b1_calc.f:(.text+0x16b): undefined reference to `calc2_'
bq_calc.o: In function `CALC2':
bq_calc.f:(.text+0x1e52): undefined reference to `calc_'
bq_calc.f:(.text+0x1ec0): undefined reference to `calc_'
collect2: error: ld returned 1 exit status
make: *** [ecis] Error 1

为什么会这样,我该如何解决?

最佳答案

[编辑,感谢 Vladimir F 和 eriktous 指出标准需要接口(interface);并因此指出我原来的(未经测试的)解决方案不太正确。]

绑定(bind)标签(bind(c)name= 部分)是 C 处理器的标识符,因此它区分大小写并且不会在最后的符号中有 gfortran 风格的装饰)。但是,如果没有可用的接口(interface),gfortran 将在 CALC2 中创建对小写符号 calc_ 的引用(在链接器输出中给出)。

所以,你需要让 gfortran/linker 知道正确的符号。您可以通过提供一个接口(interface)来做到这一点。另外,请注意,当使用 bind(c) 时,标准需要一个显式接口(interface) - 但即使不符合标准,您也可以让它“工作”。

创建显式接口(interface)的一种简单方法是使用模块:将子例程放在一个文件中,顶部/底部带有 module calcs/end module calcs。或者:

subroutine calc(...)
...
interface
subroutine calc2(...) bind(c, name='CALC2')
...
end subroutine
end interface
call CALC2(...)
end subroutine

此外,无论如何,拥有接口(interface)是件好事,因为它可以进行大量检查。

或者,将绑定(bind)标签更改为小写并附加下划线。这可能很有效,但超出了标准和特定于实现的范围。将函数放在单独的文件中会阻碍编译器检测到错误的机会。

关于c++ - 具有 C 接口(interface)的 Fortran 函数在尝试相互调用时会导致 undefined reference ,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21123278/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com