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

C++ from Fortran: dynamic array filling/passing

uzbit
Beginner
1,462 Views
I am calling some routines written in c++ which open a file and read some information (intendedfor use in my fortran code). I have not been able to pass the fortran allocated array to the c++ function in such a way that the c++ function can fill it. It seems that this should be possible, but i havnt found the correct method for doing it. Here is a snippit of what im trying to do:
C++ CODE:

extern

"C" void simion_read2 (char* file_text,double **PaArray,long nx,long ny,long nz){

FILE* pf = NULL;

int i, j, k;

double volt;

pf = fopen(file_text,"r");

if (pf != NULL){

for

(j=0;j

for(i=0;i

for(k=0;k

fread (&volt,
sizeof(double), 1, pf);

PaArray[(k*(ny+1) + j)*(nx+1)+i] = volt;

}

fclose(pf);

}

}

FORTRAN CODE:

interface

subroutine simion_read2 (file_text,p_array,nx,ny,nz)

!DEC$ ATTRIBUTES C :: simion_read2

!DEC$ ATTRIBUTES REFERENCE :: file_text, p_array

character*(*) file_text

real*8, allocatable :: p_array(:)

integer*4 nx,ny,nz

end subroutine

end interface

.....some code here......

allocate

(p_array(nx*ny*nz))

call

simion_read2('test.pa0',p_array,nx,ny,nz)

Currently this code just has access violations. When stepping through C++ code the p_array or (PaArray) is just some double pointer of a double. Any help is much appreciated.

TJ McCormack

0 Kudos
3 Replies
Steven_L_Intel1
Employee
1,462 Views
There's a section in the Programmer's Guide/User's Guide on exchanging deferred-shape arrays with C/C++. Your C code has to understand the Fortran Array Descriptor format - allocatable arrays aren't like C pointers (and in particular they aren't like C multidimension arrays which in fact are arrays of pointers to arrays.)
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,462 Views

No can do. REAL(8),ALLOCATABLE .NE. double**.

But you do not need ALLOCATABLE attribute for the PaArray in the INTERFACE block. That attribute expresses that PaArray can be allocated within simion_read2. Since you already allocate it on Fortran side, you can substitute it with normal assumed-size array, whose C equivalent is double*:
interface
   subroutine simion_read2 (file_text,p_array,nx,ny,nz) 
   !DEC$ ATTRIBUTES C :: simion_read2
   !DEC$ ATTRIBUTES REFERENCE :: file_text, p_array
   character*(*) file_text
   real*8:: p_array(*)
   ...

//----------
extern "C" void simion_read2 (char* file_text,double * PaArray,...)

Better still, you'd probably like to have a 3D array on Fortran side, which is easier to manipulate:

interface
   subroutine simion_read2 (file_text,p_array,nx,ny,nz) 
   !DEC$ ATTRIBUTES C :: simion_read2
   !DEC$ ATTRIBUTES REFERENCE :: file_text, p_array
   character*(*) file_text
   real*8:: p_array(nx,ny,*)
   ...

allocate(p_array(nx, ny, nz))
(I didn't take care about order of dimensions, which is different in C++ and Fortran -- maybe you need (nz,ny,nx) instead, depending on how you write the offset expression on C++ side)
Jugoslav
0 Kudos
uzbit
Beginner
1,462 Views
Thanks for your help, changing double **PaArray todouble *PaArray and also changing real*8, allocatable :: p_array(:) to real*8 :: p_array(*), made thecodework perfectly.
0 Kudos
Reply