从C++访问fortran模块的变量
目前我正在研究一个需要将fortran代码集成到C++的项目。在Fortran模块中声明了很多变量和数组。当相应的fortran声明为real * 8 rmax且模块的名称为common_area时,我可以通过将c变量声明为extern double common_area_mp_rmax_来访问c中的整型,浮点型和双精度类型。但是,当我尝试对数组做同样的操作时,我得到错误。从C++访问fortran模块的变量
假设FORTRAN模块中的代码是: 真实* 8,分配,尺寸(:,:我cretaed AC双指针,:) :: X
为:
extern "C" { double* common_area_mp_x_; }
现在当我编译整个项目时,它说“variable_area_mp_x_'的多重定义”。我正在使用CMake来编译整个项目。 有人可以解释我做错了什么吗?我是fortran的新手,我很难解决这个问题。我感谢你的时间和帮助。
感谢, 精神狂欢
Fortran 2003的部分采用C的互操作性为标准的Fortran语言。除非您有充分的理由相反,否则您应该使用此语言功能提供的功能。有关示例,请参阅本网站上的fortran-iso-c-binding标签。
根据当前的Fortran标准(以及下一个标准修订草案),Fortran可分配模块变量不能与C变量互操作。
在实现方面,Fortran编译器将使用描述符来存储allocatable变量的分配状态。这个描述符不仅仅是一个指向数据的指针 - 请参阅编译器用户和参考指南中的“处理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;
根据我的测试,这个问题似乎不是在fortran方面,而是在'extern double * ptr'应该用在C++代码中时使用'extern“C”double * ptr'。 –
@ J.J.Hakala从Fortran方面来说,BIND(C)关于可互操作的参数使问题消失。 OP的方法还存在其他潜在的问题。现在是2016年......对于没有为这类问题编写标准的符合性代码,很少有有效的借口。 – IanH
好的,我现在更详细地阅读fortran-iso-c-binding wiki。 –
给定一个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_;
缺少'extern'? –
实际上我没有用C语言声明extern。我只是编辑并减少这种困惑..谢谢.. – mindbender
由于它只是一个基本变量(不是结构,函数或类),所以如果需要,也许可以在头文件中省略double * common_area_mp_x_',然后在引用该变量的C++文件中声明'extern double * common_area_mp_x_'。 –