从fortran调用c ++ sub时运行时中止 [英] the run time aborting when calling c++ sub from fortran

查看:143
本文介绍了从fortran调用c ++ sub时运行时中止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里阅读了许多有关使用Fortran和C ++混合语言的文章.但是,我仍然遇到当前的问题:我的Fortran程序总是中止.

I had read many posts here about mixing languages use of Fortran and C++. However, I'm still stuck with my current problem: my Fortran program always aborted.

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

I have the Fortran program: test-cc.f90 and the C++ program: deb_cc.cc.

deb_cc.cc包含:

deb_cc.cc contains:

#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包含:

test-cc.f90 contains:

    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链接了它们. 输出为:

I compiled them by pgf90 -c test-cc.f90 and pgcpp -c deb_cc.cc Finally, I linked them by pgf90 -pgcpplibs test-cc.o deb_cc.o. The output is:

 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模块,但是您的过程接口不可与C互操作.

You use the iso_c_binding module, but your procedure interface is not C interoperable.

iso_c_binding模块不是最重要的. bind(C)属性是关键.(我曾多次抱怨标签的不幸名称)

The iso_c_binding module is not the most important thing. The bind(C) attribute is the key. (I ranted several times about the unfortunate name of the tag here)

您使用假定的形状可分配数组参数

You use an assumed shape allocatable array argument

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

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

these are not allowed in interoperable procedures in Fortran 2008, because C or C++ have no idea what to do with them. They are not just addresses. If you used the bind(C) attribute in the interface, the compiler should tell you it is wrong.

可以使用特殊的C标头在下一个Fortran标准(实际上是在现有的TS中)中传递它们,但是某些编译器(尤其是gfortran)仍然不兼容.

There is a possibility to pass them in the next Fortran standard (in an existing TS actually) using a special C header, but some compilers (notably gfortran) are still not compatible.

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

As you do not do any reallocation on the C side (at least in your example), you can just pass the array as an assumed size (array(*)) argument. I also changed the C++ name, no need for the underscore.

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端,您不能使用C数组,它们是指向指针([i] [j] [k])的指针.您从Fortran收到的是一个内存块.您还必须传递数组形状.至少在前两个Fortan维度中.

On the C side, you cannot use the C arrays which are pointers to pointers ([i][j][k]). What you receive from Fortran is a single block of memory. You also have to pass the array shape. At least in the first two Fortan dimensions.

我只会使用宏在C中对数组进行索引.

I would just use a macro to index the array in 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; 
}

这篇关于从fortran调用c ++ sub时运行时中止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆