c++ - 从 fortran 调用 c++ sub 时运行时中止

标签 c++ fortran mixing

我在这里阅读了很多关于混合使用 Fortran 和 C++ 语言的文章。然而,我仍然被当前的问题所困扰:我的 Fortran 程序总是中止。


我有 Fortran 程序:test-cc.f90 和 C++ 程序:deb_cc.cc。

deb_cc.cc 包含:

#include <iostream>
using namespace std;
extern "C" void deb_cc_(float*** rh,int* x, int* y , int* z_ext )
{
  cout <<"thinkdeb 1"<<endl;
  int i, j, k;
  cout <<"thinkdeb 1"<<endl;
  cout <<"thinktest i=8,j=4,k=1"<< " (*x) " << (*x)<<endl;
  cout <<"thinktest i=8,j=4,k=1"<< " x3/rh " << rh[1][1][1]<<endl; //abortion                        
                                                                //      here 
  cout <<"thinkdeb 7"<<endl;
  return;
}//end function

test-cc.f90 包含:

    use ISO_C_BINDING

    implicit none

    interface
      subroutine  deb_cc( rh,x,y,z_ext)
        use ISO_C_BINDING
        implicit none
        real(c_float),allocatable::rh(:,:,:)
        integer(c_int):: x,y,z_ext
      end subroutine
    end interface

    integer nx,ny,nz
    parameter (nx=10,ny=10,nz=10)
    real  ,dimension (:,:,:),allocatable:: x1
    integer:: iy1,iy2,iy3,iy4
    integer i,j,k

    allocate(x1(nx,ny,nz))

    do k=1,nz
      do j=1,ny
        do i=1,nx
          x1(i,j,k)=k*1000+j*100+i
        enddo
      enddo
    enddo

    iy1=nx
    iy2=ny
    iy3=nz

    call deb_cc(x1,iy1,iy2,iy3)

  end

我通过 pgf90 -c test-cc.f90pgcpp -c deb_cc.cc 编译了它们 最后,我通过 pgf90 -pgcpplibs test-cc.o deb_cc.o 链接它们。 输出是:

 thinktest in test- x1 (8,2,2) is     2208.000
 thinkdeb 1
 thinkdeb 1
 thinktest i=8,j=4,k=1 (*x) 10
 Segmentation fault (core dumped)

最佳答案

您使用 iso_c_binding 模块,但您的过程接口(interface)不是 C 可互操作的。

iso_c_binding 模块不是最重要的。 bind(C) 属性是关键。(我在这里多次提示标签的不幸名称)

你使用一个假设的形状可分配数组参数

real(c_float),allocatable::rh(:,:,:)

在 Fortran 2008 的互操作过程中不允许使用这些,因为 C 或 C++ 不知道如何处理它们。它们不仅仅是地址。如果您在接口(interface)中使用了 bind(C) 属性,编译器应该会告诉您这是错误的。

有可能使用特殊的 C 头文件将它们传递到下一个 Fortran 标准(实际上是在现有的 TS 中),但是一些编译器(特别是 gfortran)仍然不兼容。

因为您没有在 C 端进行任何重新分配(至少在您的示例中),您可以将数组作为假定大小 (array(*)) 参数传递。我还更改了 C++ 名称,不需要下划线。

interface
  subroutine  deb_cc(rh,x,y,z_ext) bind(C, name="deb_cc")
    use ISO_C_BINDING
    real(c_float) :: rh(*)
    integer(c_int):: x,y,z_ext
   end subroutine
end interface

在 C 端,您不能使用指向指针 ([i][j][k]) 的指针的 C 数组。您从 Fortran 收到的是单个内存块。您还必须传递数组形状。至少在前两个 Fortan 维度上。

我只会用一个宏来在 C 中索引数组。

// adjust as needed, many variants possible
#define IND(i,j,k) = i + (j-1) * nx + (k-1) * nx * ny
// adjust as needed, many variants possible


extern "C" void deb_cc(float *rh, int *nx, int *ny, int *nz) {
  cout <<"thinktest i=8,j=4,k=1"<< " x3/rh " << rh(IND(8,4,1))<<endl; 
}

关于c++ - 从 fortran 调用 c++ sub 时运行时中止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29132606/

相关文章:

iphone - 使用 OpenAl 混合声音

c++ - 免费运营商与成员(member)运营商

fortran - 如何在 Fortran 中计算大整数?

Fortran:将任意 "structures"传递给模块子例程

java - JComboBox 隐藏在 awt Canvas 后面

c++ - 从 C++ 对象调用 Objective-C 父对象

c++ - 将目录从编译器传递到 C++ 应用程序

c++ - Visual C++ 按钮的透明背景颜色

C++ 模板 : retain non-type value info without store in the constructor

segmentation-fault - 为什么 Fortran 代码会出现段错误?