为什么将指针从C++传递到Fortran的尝试不起作用

Why is this attempt to pass a pointer from C++ to Fortran not working?

本文关键字:Fortran 不起作用 指针 C++ 为什么      更新时间:2023-10-16

我需要将一个动态数组从c++传递给Fortran。我做了很多研究,把一个我认为应该有效的例子放在一起,但事实并非如此。程序应该在c++程序中创建一个数组,将该数组的指针传递给Fortran例程,将c指针转换为Fortran指针,然后在Fortran端打印该数组。

我的c++主程序:

using namespace std;
extern "C" {
   void cinterface(int*,int*);
}
int main()
{
   int carray[]={0,1,2,3,4};
   int carray_siz=5;
   cinterface(&carray_siz,carray);
   return 0;
}

我的Fortran例程:

module fortmod
   use ISO_C_BINDING
   implicit none
contains
   subroutine cinterface(carray_siz,carray_ptr) bind(C)
      implicit none
      integer(c_int), intent(in) :: carray_siz
      type(c_ptr), intent(in) :: carray_ptr
      integer(c_int), pointer :: pfarray(:) => NULL()
      call C_F_POINTER(carray_ptr,pfarray,[carray_siz])
      print *, pfarray
   end subroutine cinterface
end module fortmod

我将其构建为:

gfortran -c fortmod.f90
g++ main.cpp fortmod.o -lgfortran

但当我运行它时,它没有打印数组值,而是显示:

Segmentation fault (core dumped)

我对指针的概念很陌生,所以我想我不明白它们是如何正确工作的。你能指出我运行这个程序时出现内存错误的原因吗?

您肯定想将数组大小传递为int,而不是大小的地址:

extern "C" {
    void cinterface(int,int*);
}
cinterface(carray_siz,carray);

来自gfortran手册:

如果指针是可互操作过程的伪参数,那么它通常必须使用VALUE属性声明。void*与TYPE(C_PTR)、VALUE匹配,而TYPE(C_PTR)单独与void**匹配。

我的Fortran例程是在寻找指针的地址,而不是指针所指向的地址。因此,如果我将c++端修改为:

使用命名空间std;

extern "C" {
   void cinterface(int*,int**);
}
int main()
{
   int carray[]={0,1,2,3,4};
   int carray_siz=5;
   cinterface(&carray_siz,&carray);
   return 0;
}

重新构建并重新运行,我现在得到:

0     1     2     3     4

正如预期的那样。