javacavaj
javacavaj

Reputation: 2961

Passing Multidimensional C Array to FORTRAN Function for Modification

I'm attempting to pass a multidimensional array, initialized in C, to a FORTRAN function and modify the array elements. I found a similar question here, but I've been unable to get it working with the multidimensional array. Attempting to write to the array results in a core dump. What am I missing?

Code example:

#include <stdio.h>
#include <stdlib.h>

double f_function(double ****);

double ****alloc_4D_double(int wlen, int xlen, int ylen, int zlen)
{
    int i,j,k;

    double ****ary = (double****)malloc(wlen*sizeof(double***));

    for (i = 0; i < wlen; i++) 
    {
        ary[i] = (double***)malloc(xlen*sizeof(double**));

        for (j = 0; j < xlen; j++) 
        {
            ary[i][j] = (double**)malloc(ylen*sizeof(double*));

            for (k = 0; k < ylen; k++) 
            {
                ary[i][j][k] = (double*)malloc(zlen*sizeof(double));
            }
        }
    }

    return ary;
}

int main ( void ) {

    double ****cary = alloc_4D_double(2, 2, 2, 2);

    // intialize values
    for (j=0; j < 2; j++)
    {       
        for (k=0; k < 2; k++)
        {
            for (l=0; l < 2; l++)
            {
                for (m=0; m < 2; m++)
                {
                    cary[j][k][l][m] = 0;
                }
            }
        }
    }   

    f_function (cary);

    return 0;
}

and

    real(4) function f_function(cary)
        use, intrinsic :: iso_c_binding    
        !DEC$ ATTRIBUTES C :: f_function

        implicit none    

        real(c_double)        , intent(out), dimension(2,2,2,2) :: cary

        ! attempt to overwrite value (core dump!)
        cary=1.1_c_double

        ...

    end function f_function

Upvotes: 1

Views: 662

Answers (2)

M. S. B.
M. S. B.

Reputation: 29381

I suggest using the ISO_C_BINDING in Fortran and the intrinsic from the module c_f_pointer, which will associate a C pointer with a Fortran array. There is an example in the gfortran manual under "Mixed Language Programming".

Upvotes: 0

user1220978
user1220978

Reputation:

In Fortran, multidimensional arrays are stored as contiguous data in memory.

However, you declare your multidimensional array in C by pointer to pointers to... Obviously Fortran don't know what to do with this.

You simply have to malloc(wlen*xlen*ylen*zlen*sizeof(double)), and pass this single pointer to your Fortran program.

If you badly need your multiple pointer representation, you can first allocate your data array as contiguous data with a single malloc, and then allocate your pointers to pointers, making them ultimately point inside the data array. And like previously, you pass to Fortran only the pointer to data array. Thus Fortran won't see the multiple pointers, but you will still be able to use them in C.

Upvotes: 2

Related Questions