从c ++访问fortran模块的变量

时间:2016-01-22 02:50:46

标签: c++ fortran intel-fortran fortran-iso-c-binding

目前我正在开发一个需要将fortran代码集成到c ++的项目。在fortran模块中,声明了许多变量和数组。我可以通过将相应的fortran声明为real * 8 rmax并且模块的名称为common_area时将c变量声明为extern double common_area_mp_rmax_来从c访问integer,float和double类型。但是,当我尝试对数组执行相同操作时,我收到错误。

假设fortran模块中的代码是: 真* 8,可分配,维度(:,:,:) :: x

我创造了一个c双指针:

extern "C" { double* common_area_mp_x_; }

现在当我编译整个项目时,它说“`variable_area_mp_x_'的多重定义”。我正在使用CMake编译整个项目。 有人可以解释我做错了吗?我是fortran的新手,我很难解决这个问题。感谢您的时间和帮助。

谢谢, 精神狂欢

2 个答案:

答案 0 :(得分:6)

Fortran 2003将与C的互操作性引入标准的Fortran语言。除非您有充分的理由相反,否则您应该使用此语言功能提供的功能。有关示例,请参阅此站点上的标记。

根据当前的Fortran标准(以及下一个标准修订版的草案),Fortran可分配模块变量不能与C变量互操作。

在实现方面,Fortran编译器将使用描述符来存储可分配变量的分配状态。此描述符不仅仅是指向数据的指针 - 有关详细信息,请参阅编译器的“用户和参考”指南中的“处理Fortran数组描述符”。

在这种情况下共享信息的最佳方法取决于您尝试做什么。一种选择是为可分配数组赋予TARGET属性,然后使用一个单独的TYPE(C_PTR)变量,其带有一个带有目标C地址的绑定标签。诸如阵列大小之类的方面需要单独传达。

MODULE common_area
  USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_DOUBLE
  IMPLICIT NONE
  ...
  REAL(C_DOUBLE), ALLOCATABLE, TARGET :: x(:,:,:)
  TYPE(C_PTR), BIND(C, NAME='x_ptr') :: x_ptr
CONTAINS
  ! Call before operating on x_ptr in C++
  SUBROUTINE init
    USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_LOC
    ALLOCATE(x(1,2,3))
    x_ptr = C_LOC(x)
  END SUBROUTINE init

~~~

// After init has been executed, this is a 
// pointer to the value of the allocatable module variable
extern "C" double *x_ptr;

答案 1 :(得分:2)

给出带有内容

的C ++文件 test.cpp
extern "C" { double * foo; }
extern double bar;
double asdf;

使用gnu工具

g++ -Wall -c test.cpp; nm test.o
> 0000000000000000 B asdf
> 0000000000000008 B foo

即。使用第一个选项实际上引入了一个具有该名称的新符号。

在这种情况下,正确的选择是

extern double * common_area_mp_x_;