编译 Fortran 和C++程序并从英特尔编译器链接

Compiling fortran and C++ program and linking from intel compiler

本文关键字:英特尔 编译器 链接 程序 Fortran C++ 编译      更新时间:2023-10-16

我有一个Fortran主程序,它下有很多子程序。其中一个子例程调用 c++ 函数。该 c++ 函数正在调用另一个 Fortran 子例程。现在我需要将它们编译在一起以获得输出。 我尝试使用 icl 编译 c++ 文件。然后我使用 ifort 作为 Fortran 文件和为 c++ 创建的目标文件之间的链接器。但是这种方法不起作用。它显示未解析的外部符号。

我希望你至少看到了这个:https://software.intel.com/en-us/node/691954

他们在那里写的东西主要是指C,尽管提到了C++库。如果你链接到C++ocde,你需要这些。 您应该在C++中阅读有关符号名称重整的信息。 由于C++支持重载功能,但链接器需要唯一的符号,因此C++生成 类似于函数 foo(int i, float j( 的_foo****@8而不是foo,其中 * 取决于编译器和参数类型。

Fortran 代码生成 C 样式的符号 如果使用 BIND(C(,您可以强制C++为函数生成一个符号,方法是在C++代码中使用extern "C",用于从C++调用的 fortran 函数的原型和将从 fortran 调用的函数。

此示例适用于 C 编译器,但对于C++,您需要更改生成的符号 (https://software.intel.com/en-us/node/691929#92BDCE7A-30FA-4A60-BCDB-7CE1521572EC(。请注意,C 和 Fortran 互操作性不是标准化的,通常不能从一个编译器集移植到另一个编译器集。我不得不处理康柏编译器也在修改函数名称的问题,但不是以C++方式,或者PGI Fortran需要标准调用约定的问题。

Fortran 代码示例

subroutine Simulation(alpha, beta, gamma, delta, arrays) BIND(C) 
use, intrinsic :: ISO_C_BINDING 
implicit none 
integer (C_LONG), value :: alpha 
real (C_DOUBLE), intent(inout) :: beta 
integer (C_LONG), intent(out) :: gamma 
real (C_DOUBLE),dimension(*),intent(in) :: delta
type, BIND(C) :: pass 
integer (C_INT) :: lenc, lenf
type (C_PTR) :: c, f 
end type pass 
type (pass), intent(inout) :: arrays
real (C_FLOAT), ALLOCATABLE, target, save :: eta(:)
real (C_FLOAT), pointer :: c_array(:) 
... 
! Associate c_array with an array allocated in C 
call C_F_POINTER (arrays%c, c_array, (/arrays%lenc/) ) 
... 
! Allocate an array and make it available in C 
arrays%lenf = 100 
ALLOCATE (eta(arrays%lenf)) 
arrays%f = c_loc(eta) 
... 
end subroutine Simulation

C 结构声明示例

struct pass {int lenc, lenf; float *c, *f;};

C 函数原型示例

void simulation(long alpha, double *beta,
long *gamma, double delta[], struct pass *arrays);

C 调用序列示例

simulation(alpha, &beta, &gamma, delta, &arrays);