- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - theithecker
Any examples out there?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]
//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]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]
#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).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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).
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