Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29277 Discussions

passing a two dimensional array from C to fortran

asalterain
Beginner
890 Views

C part **********

typedef long(__stdcall * tDll_Ptr_TEST0) (double **, int, int);
..

int rows=10, columns=10;
double ** matrix;
matrix = new double *[rows];
for(i=0; imatrix= new double [columns];
}

...

for( i=0; ifor(j=0; jmatrix=1.25;
}
}
myTEST0(matrix, rows, columns);
..

Fortran Part (Fotran DLL) *************

SUBROUTINE TEST0(TEMP, ROW, COLUMN )

! Expose subroutine TransportDll to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::TEST0

! Variables
!DEC$ ATTRIBUTES REFERENCE :: TEMP! This argument is passed by REFERENCE
!DEC$ ATTRIBUTES VALUE :: ROW! This argument is passed by VALUE
!DEC$ ATTRIBUTES VALUE :: COLUMN! This argument is passed by VALUE
!
! UFComServerTY.f90 - This module contains user-defined class
! definitions and methods


INTEGER ROW, COLUMN
REAL*8 TEMP(COLUMN, ROW)
!!================================================!!

do i=1, row
do j=1, COLUMN
write(*,*) TEMP(i,j)
enddo
write(*,*)
enddo

WRITE(*,*) ' leaving TESTTTTTTTTTTT0 '
READ(*,*)

RETURN


END SUBROUTINE TEST0

When I execute the C main programme I get garbage.ANY HELPPPPPP ????????



0 Kudos
5 Replies
TimP
Honored Contributor III
890 Views
You have C++ syntax, which should not compile unless you use a C++ compiler. The standard way to negotiate the linkage question is with extern "C" on the C++ side, and ISO C binding on the Fortran side (requires a current Fortran).
Assuming you didn't fall prey to the complications you introduced in linking, you still must understand that a Fortran 2d array corresponds to a C 1d array. For example, you could make your C code look a lot like Fortran with a macro
#define MATRIX(i,j) matrix((j-1)*10 + i -1)
with matrix being a 1d array of size 100.
Your C++ code defines something which would look on the Fortran side like a 1d array of type c_ptr, each element of which points to the first element of a 1d array of type c_double. I haven't seen any fully working examples.
0 Kudos
Steven_L_Intel1
Employee
890 Views
C doesn't really have arrays - it has pointers with an indexing syntax. Furthermore, as Tim implies, what you think of as a two-dimensional array in C is actually an array of pointers to arrays. As Tim says, you'll have to adjust for this either in the Fortran code or the C code.
0 Kudos
asalterain
Beginner
890 Views

Yes, I am using C++ complierbut the point is that if I define matrix as:

typedef long(__stdcall * tDll_Ptr_TEST0) (double (*)[10], int, int);
...

int rows=10, columns=10;

double matrix [rows][colums];

for( i=0; ifor(j=0; jmatrix=1.25;
}
}
myTEST0(matrix, rows, columns);

the everything goes OK.

I think the problem is the way pointers are passed. No problems with vectors (I have already done it). However, the problem is that I havethe main C++ that declares a dynamic two dimensional martrix and I want pass it to the fotran subroutine (in a fortran Dll) efficiently and easily.

0 Kudos
Steven_L_Intel1
Employee
890 Views
I note that you have __stdcall in there - which compiler are you using?
0 Kudos
TimP
Honored Contributor III
890 Views
It's possible that your C declaration local to the calling function happens to put matrix[][] in contiguous memory, such that matrix[] happens to point to the correct block of data for a Fortran compiler which uses call by reference. This is not portable, even to more complicated situations with the same C++ compiler. Even if it does "work," you have subscript reversal, unless you have a Fortran compiler with the non-standard option to reverse them to correspond with C.
There no longer are good reasons to recommend non-portable syntax for situations which are covered in standards.
0 Kudos
Reply