我有一个Fortran主程序,其中有许多子程序。其中一个子程序调用c ++函数。该c ++函数正在调用另一个Fortran子例程。现在我需要将所有这些编译在一起以获得输出。 我试图用icl编译c ++文件。然后我使用ifort作为Fortran文件和为c ++创建的目标文件之间的链接器。但该方法无效。它显示未解决的外部符号。
答案 0 :(得分:0)
我希望你至少看到这个:https://software.intel.com/en-us/node/691954
他们在那里写的内容主要是指C,尽管提到了C ++库。如果你用C ++ ocde链接,你需要那些。
您应该阅读C ++中的符号名称修改。因为C ++支持重载的funktions但链接器需要唯一的符号,所以C ++会生成
对于函数foo(int i,float j),类似_foo****@8
而不是foo
,其中*取决于编译器和参数类型。
如果使用BIND(C),Fortran代码会生成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互操作性没有标准化,并且通常无法从一个编译器集移植到另一个编译器集。我不得不处理Compaq编译器破坏函数名称的问题,但不是用C ++方式,或PGI Fortran需要stdcall约定。
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声明示例
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);