- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello All,
I tried to pass a dynamic allocated 2D array to a Fortran DLL subroutine in C++.
Please check the following codes. Output on the screen reads like:
4.240000 3.240000 5.240000
4.240000 3.240000 5.240000
4.240000 3.240000 5.240000
4.240000 3.240000 5.240000
4.240000 3.240000 5.240000
4.240000 3.240000 5.240000
4.240000 3.240000 5.240000
4.240000 3.240000 5.240000
6.115449276184175E-307 6.117241938228800E-307 0.000000000000000E+000
0.000000000000000E+000 4.24000000000000 -2.530171125652461E-098
3.897964094641386E-308 2.121995802822848E-314
6.116046830199050E-307 -2.530171125652461E-098 3.897987436627466E-308
2.121995802822848E-314 3.24000000000000 -2.656983832617227E+303
6.115639407007020E-307 -7.845907716021313E+298
6.116644384213925E-307 -2.656983832617227E+303 6.115340629999576E-307
-7.845907716021312E+298 5.24000000000000 0.000000000000000E+000
0.000000000000000E+000 4.24000000000000
It looks like C++ did not pass correct address/values to Fortran.
Please give me some hints and suggestions.
Thank you.
//------------------------------------------------------------------------------------------------------------------------------
/* Main program written in C++ that calls a Fortran routine */
//------------------------------------------------------------------------------------------------------------------------------
#include
#include
#include
#ifdef __cplusplus
extern "C"
#endif
#ifdef USEDLL
__declspec(dllimport)
#endif
void TESTDLL(double **); // Fortran DLL Subroutine
void updateinput(double **);
void main ()
{
//double log_DATA_TEMP[8][3];
double **log_DATA_TEMP;
int i;
log_DATA_TEMP=new double* [8];
for (int i=0; i<8; ++i) {
log_DATA_TEMP=new double [3];
for (int j=0; j<3; ++j) {
log_DATA_TEMP
}
}
updateinput(log_DATA_TEMP);
for (i=0;i<8;i++)
{
printf("%lf %lf %lf\\n",log_DATA_TEMP[0],log_DATA_TEMP[1],log_DATA_TEMP[2]);
}
TESTDLL(log_DATA_TEMP);
for(i = 0; i < 8; i++)
delete(log_DATA_TEMP);
delete(log_DATA_TEMP);
}
void updateinput(double **DATA)
{
int i;
for (i=0;i<8;i++)
{
DATA[0]=4.24;
DATA[1]=3.24;
DATA[2]=5.24;
}
}
!---------------------------------------------------------------------------------------------------------------
! TESTDLL.f90
!---------------------------------------------------------------------------------------------------------------
! FUNCTIONS/SUBROUTINES exported from TESTDLL.dll:
subroutine TESTDLL(inputdata)
! Expose subroutine TESTDLL to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::TESTDLL
Real(8)::inputdata(3,8);
Integer::i
!
Do i=1,3
Write(*,*) inputdata(i,:)
Write(*,*)
Enddo
end subroutine TESTDLL
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are passing an pointer-to-pointer-to-double (an array of arrays, two levels of indirection) to a fortran function that just expects a pointer-to-double (just one big array, one level of indirection). double[] and double ** aren't the same thing, despite what the syntax might suggest.
Best option if your array is rectangular is to just create one chunk of memory on the C++ side:
Reference the memory on the fortran side as input_data(j,i).
Alternatively, make the fortran handle two levels of indirection:
Apologies if my head C++ compiler/Fortran processor has failed me.
Best option if your array is rectangular is to just create one chunk of memory on the C++ side:
[cpp]extern "C" void TESTDLL(double *); ... double* log_DATA_TEMP = new double [8 * 3]; // in C++ consider using std::vector ... log_DATA_TEMP[i*3+j] = some_value; ... TESTDLL(log_DATA_TEMP); delete [] log_DATA_TEMP; // note array delete [/cpp]
Reference the memory on the fortran side as input_data(j,i).
Alternatively, make the fortran handle two levels of indirection:
[fortran]subroutine TESTDLL(input_data) BIND(C, NAME='TESTDLL') USE ISO_C_BINDING, ONLY: C_DOUBLE, C_PTR, C_F_POINTER TYPE(C_PTR), INTENT(IN) :: input_data(*) REAL(C_DOUBLE), POINTER :: array(:) ... DO i = 1, 8 CALL C_F_POINTER(input_data(i), array, [3]) DO j = 1, 3 ! do something with array(j)... ...[/fortran]This potentially allows you to process "arrays" with varying row lengths.
Apologies if my head C++ compiler/Fortran processor has failed me.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello IanH,
Thank you a lot.
I also did some extra homework here. Thoese two solutions suggested by you should be good approaches.
Thanks again.
Thank you a lot.
I also did some extra homework here. Thoese two solutions suggested by you should be good approaches.
Thanks again.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page