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

Passing and receiving multidimensional arrays from C++ to IVF 10.1

theithecker
Beginner
772 Views
Any examples out there? I need to pass, say, a 2-d array of floats from a C++(VS2005) wrapper to a Fortran(IVF 10.1) all, by reference, modify values in Fortran, then return to C++. For ease of discussion I would like to use a 2-d array of floats such as:

float carray[3][5];

My questions are:

What do I pass from C++? A pointer to an array of floats? Does this require creating the pointer as:

float (*carray)[][5]

And, how do I receive this in Fortran, since the order is reversed?

REAL FARRAY(5, 3) ???

(I have a subroutine using RESHAPE to switch the shape of the array from C to Fortran and vice versa, its more the memory/passing that is confusing me.

thanks in advance,

-troy
0 Kudos
4 Replies
TimP
Honored Contributor III
772 Views
Quoting - theithecker
Any examples out there?
Which examples have you looked at and discarded? Do you have an example showing specifically how you want to do it differently, so we could comment?
0 Kudos
theithecker
Beginner
772 Views
Okay. Got this to work realatively simply. Simply pass the 2-d array (e.g. float carray[3][5]) to fortran using _stdcall. In fortran I use RESHAPE to change to array back into C format. Do my work in Fortran, reshape again, and return. Thats it. Annotated pseudo-code:

//C++

//Header
extern "C" __declspec(dllimport) void _stdcall VOLUMELIBRARY(...float LOGVOL[7][20],...);

//main
float LOGVOL[7][20];

//calling the fortran subroutine from C++
VOLUMELIBRARY(...LOGVOL,...);

!Fortran
subroutine VOLUMELIBRARY(...LOGVOLC...)

REAL LOGVOL(I7,I20), LOGVOLC(I20, I7) !note the subscript order is reversed in Fortran

!reshape the array into the original c format, used in other subs in fortran dll
LOGVOL = RESHAPE(LOGVOLC, SHAPE(LOGVOL))

!code, subroutine calls, etc., ...

LOGVOLC = RESHAPE(LOGVOL, SHAPE(LOGVOL))

RETURN

In C++ I know either just keep track of the subscripting/access difference or use a Macro (I know, I know) so I can access the C++ array identically to the Fortran side.

#define LOGVOL(i,j) LOGVOL[j-1][i-1]
0 Kudos
Jugoslav_Dujic
Valued Contributor II
772 Views
Quoting - theithecker
In C++ I know either just keep track of the subscripting/access difference or use a Macro (I know, I know) so I can access the C++ array identically to the Fortran side.

#define LOGVOL(i,j) LOGVOL[j-1][i-1]

Personally, I don't have any problem with using macros in C++ when they're called for (think e.g. of STL iterators). However, I dislike the approach where you emulate Fortran array semantics in C++: I think they're bound to confuse poor reader. I prefer to have C++ array semantics in C++ (indices start at 0), and Fortran array semantics in Fortran. But each to his own.

Note that RESHAPE can take some time (because it involves array copying), and is not efficient for large arrays. Is there a particular reason why you didn't just work with indices reversed (i.e. no RESHAPE)?

Style matters aside, the approach you took is generally correct. Note, however, that C++ allows Fortran 2-D array semantics only if the bounds are constant and known in advance. In other words, you can declare:

float X[5][3];

but not

float X[nRow][nCol];

where nRow and nCol are variables. If you need the latter, you would have to malloc/new a 1-D array (pointer) and write "row/column" access by hand (or, nicer still, hide it behind a template class).
0 Kudos
TimP
Honored Contributor III
772 Views
Quoting - Jugoslav Dujic

Personally, I don't have any problem with using macros in C++ when they're called for (think e.g. of STL iterators).
I agree for the most part with Jugoslav. I'll mention at this point that f2c (one of the first f77 translators) implements Fortran multiple subscripted arrays as linear C arrays, and compiles in the equivalent of a macro to calculate the linear address. So there is always a direct correspondence between f77 arrays and 1-D C arrays. Speaking of C++ STL, that also has better support for 1-D arrays than for multiple dimensions.
0 Kudos
Reply