ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

从fortran调用c sub时运行时间中止

2019-10-07 14:05:26  阅读:243  来源: 互联网

标签: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.f90和pgcpp -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模块,但您的过程接口不是C可互操作的.

iso_c_binding模块不是最重要的事情. bind(C)属性是关键. (我在这里对标签的不幸名称多次咆哮)

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

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

这些在Fortran 2008中的可互操作程序中是不允许的,因为C或C不知道如何处理它们.它们不仅仅是地址.如果您在接口中使用了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端,您不能使用指向指针的C数组([i] [j] [k]).你从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,mixing
来源: https://codeday.me/bug/20191007/1867364.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有