【问题标题】:Why is this attempt to pass a pointer from C++ to Fortran not working?为什么这种将指针从 C++ 传递到 Fortran 的尝试不起作用?
【发布时间】:2013-11-27 18:02:24
【问题描述】:

我需要将一个动态数组从 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)

我对指针的概念不熟悉,所以我想我不明白它们是如何正常工作的。您能否指出为什么我在运行此程序时会出现此内存错误?

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 但是Fortran通过引用传递参数,所以我想我确实想传递地址,对吧?
    • 在这种情况下,您想传递数组地址的 address(即它的引用以及 carray_siz 引用)
    【解决方案2】:

    来自 gfortran 手册:

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

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

    使用命名空间标准;

    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
    

    正如预期的那样。

    【讨论】:

      猜你喜欢
      • 2013-07-06
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多