将动态二维数组从C ++传递到Fortran并返回 [英] Passing a dynamic 2D array from C++ to Fortran and back

查看:784
本文介绍了将动态二维数组从C ++传递到Fortran并返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++和Fortran之间传递一个固定的二维数组可以很好地工作,但是我写过的程序并没有将从C ++到Fortran的二维动态数组传递出去。



C ++端

  externC{void array2d_(double **,int *,int *); } 
使用namespace std;
int main()
{
double ** array;
int nx = 3;
int ny = 2;
int i,j;
cout<< 将动态数组从C传递给Fortran \\\
;
array =(double **)malloc(nx * sizeof(double *));
if(array == NULL)
{
fprintf(stderr,out of memory \\\
);
出口;
}
for(i = 0; i {
array [i] =(double *)malloc(ny * sizeof(double));
if(array [i] == NULL)
{
fprintf(stderr,out of memory \\\
);
出口; (i = 0; i {
for(j = 0; j
}
b $ b {
array [i] [j] = i + j + i *(2 + j)+4; //随机初始化
cout<< array [<<我<< ] [<< j<< ] =<<数组[i] [j]<< ;
}
cout<< ENDL;
}

array2d_(array,& nx,& ny); (i = 0; i< nx; i ++)
free(array [i]);


free(array);
返回0;
}

Fortran方面

< (c,name =array2d_)
使用iso_c_binding
隐式无
整型(C_INT)$ p $ 子程序array2d(arr,nx_C,ny_C) ,intent(IN):: nx_C,ny_C!数组大小从C
real(C_DOUBLE),intent(INOUT):: arr(ny_C,nx_C)
integer :: k,l
print *,这是在Fortran例程中...
do k = 1,ny_C
do l = 1,nx_C
print *,arr(,k,, ,l,)=,arr(k,l)
end do
end do
end subroutine array2d

C ++中的输出是

$ p $ array [0] [0] = 4 array [0] [1] = 5
array [1] [0] = 7 array [1] [1] = 9
array [2] [0] = 10 array [2] [1 ] = 13

在Fortran中,输出是

(1,3)= 9.8813129168249309($) E-324
ar r(2,1)= 5.4809152658772852E-317
arr(2,2)= 1.5475240269406953E-314
arr(2,3)= 0.0000000000000000

所以不知何故值不能正确传递。

解决方案

主要原因是你的C数组是一个锯齿形数组,它是一个指向数组的指针数组,当你在Fortran中声明它的参数是一个连续的二维数组时。



只需 malloc 一个大的元素,最好在C中使用相同的数组。 nx * ny 缓冲区,并将指针设置为行而不是分配它们。您可以在 https://stackoverflow.com/a/5901671/721644 中查看示例。


Passing a fixed 2D array between C++ and Fortran works fine, however not so with the program I have written to pass a 2D dynamic array from C++ to Fortran.

C++ side

extern "C" {void array2d_(double **, int *, int *); }
using namespace std;
int main()
{
double **array;
int nx=3;
int ny=2;
int i,j;
cout << "Passing dynamic array from C to Fortran\n";
array = (double **) malloc(nx * sizeof(double *));
if(array == NULL)
        {
        fprintf(stderr, "out of memory\n");
        exit;
        }
for(i = 0; i < nx; i++)
        {
        array[i] = (double *) malloc(ny * sizeof(double));
        if(array[i] == NULL)
            {
            fprintf(stderr, "out of memory\n");
            exit;
            }
        }
for(i = 0; i < nx; i++)
            {
            for(j = 0; j < ny; j++)
                {
                array[i][j]=i+j+i*(2+j)+4;  //random initialisation
                cout << "array[" << i << "][" << j << "]=" << array[i][j] << " ";
                }
            cout << endl;
            }

array2d_(array, &nx, &ny);

for(i = 0; i < nx; i++)
        free(array[i]);
    free(array);
return 0;
}

The fortran side

subroutine array2d(arr,nx_C,ny_C) bind(C,name="array2d_")
use  iso_c_binding
implicit none
integer (C_INT), intent(IN) :: nx_C,ny_C          !array sizes from C
real (C_DOUBLE), intent(INOUT) :: arr(ny_C,nx_C)
integer :: k,l
print *, "This is in Fortran routine..."
do k = 1,ny_C
do l=1,nx_C
 print *, "arr(",k,",",l,") = ", arr(k,l)
end do
end do
end subroutine array2d

The output in C++ is

 array[0][0]=4 array[0][1]=5 
 array[1][0]=7 array[1][1]=9 
 array[2][0]=10 array[2][1]=13 

While in Fortran the output is

 arr(           1 ,           1 ) =    1.7994937190948764E-305
 arr(           1 ,           2 ) =    7.1027035167764720E-251
 arr(           1 ,           3 ) =    9.8813129168249309E-324
 arr(           2 ,           1 ) =    5.4809152658772852E-317
 arr(           2 ,           2 ) =    1.5475240269406953E-314
 arr(           2 ,           3 ) =    0.0000000000000000  

So somehow the values are not passed correctly.

解决方案

The main reason is that your C array is a jagged array, it is an array of pointers to separate 1D arrays while in Fortran you declare ther argument to be a contiguous 2D array. You must use the same in both parts, preferably use a contiguous array in C too.

Just malloc one big nx*ny buffer and set the pointers to the rows instead of alloacating them. You can see an example in https://stackoverflow.com/a/5901671/721644

这篇关于将动态二维数组从C ++传递到Fortran并返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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