Passing Fortran arrays to C

笑着哭i 提交于 2019-12-23 02:02:55

问题


I am having a lot of trouble passing Fortran arrays to a C program. From what I have gathered from previous posts is the inclusion of the interface. That got rid of some of my problems. However, I cannot seem to figure out how to pass these arrays properly or access their values correctly inside C.

program f_call_c
  implicit none


  interface
     subroutine cfun(x,len) bind( c )
       use,intrinsic :: iso_c_binding
       implicit none
       integer( c_int) :: len
       real(c_double) :: x(0:3,0:len)
     end subroutine   cfun

     subroutine vec(r,len) bind(c)
       use,intrinsic :: iso_c_binding
       implicit none
       integer(c_int) :: len
       real(c_double) :: r(0:len)
     end subroutine vec


  end interface


  double precision, allocatable :: x(:,:),r(:)
  integer :: len,row,i,j

  len = 7
  allocate(x(0:3,0:len))
  allocate(r(0:len))

  do i =0,len
     r(i) = i
  enddo


  do i = 0,len
     do j = 0,3
        x(j,i) = j+i
     enddo
  enddo

  call vec(r,%val(len) )

  row = 3
  call cfun(x,%val(len))
end program f_call_c


#include <stdio.h>
void cfun(double **x,const int len)
{
  printf("%d\n", len);
  printf("This is in C function cfun...\n");


  for(int i=0; i<len; i++)
    {
      printf(" %d\n  %d\n  %d\n", x[0][i]);

    }
}

void vec(  double *r[],const int len )
{
  printf("This is in C function vec...\n");

  printf("%d\n", len);

  for(int i=0; i<len; i++)
    {
       printf(" %d\n", r[i]);

    }

}

Currently, the output is

    Fortran calling C, passing
 r at           0 is   0.0000000000000000     
 r at           1 is   1.0000000000000000     
 r at           2 is   2.0000000000000000     
 r at           3 is   3.0000000000000000     
 r at           4 is   4.0000000000000000     
 r at           5 is   5.0000000000000000     
 r at           6 is   6.0000000000000000     
 r at           7 is   7.0000000000000000     
This is in C function vec...
7
 0
 0
 0
 0
 0
 0
 0
7
This is in C function cfun...
Segmentation fault (core dumped)

Any suggestions?


回答1:


You can't recieve a fortran array in c as double **, it should be double *, so try this

#include <stdio.h>

void cfun(double *x, const int len)
{
    printf("%d\n", len);
    printf("This is in C function cfun...\n");

    for (int i = 0 ; i < len ; i++)
    {
        printf(" %d\n  %d\n  %d\n", x[i]);
    }
}

in fact if you have a c double ** array of pointers you should join the arrays into a single array to pass it to fortran, see for example how to use Lapack in c.

The reason is that in in a fortran 2d array is stored contiguously, whereas in c double ** is an array of pointers, and hence the values are not contiguously stored.

Note that when printing the values, you will print wrong values, because you are not using the appropriate format specifier for double you should fix the printf line to make it look like this

printf(" %f\n  %f\n  %f\n", x[i]);


来源:https://stackoverflow.com/questions/28003625/passing-fortran-arrays-to-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!