编译fortran和C ++程序并从intel编译器链接

时间:2017-08-03 06:57:01

标签: c++ fortran intel-fortran

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

1 个答案:

答案 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);
相关问题