472,353 Members | 1,414 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,353 software developers and data experts.

Passing a 2 dimensional array from c++ to fortran

Sam

Hello all
I have a two dimensional array (the dimensions are not known) that
needs to be passed
to fortran from c++, allocate the dimensions of the array in fortran
code, do some filling up
of the array in fortran and then accessing it in my c++ code.

Say in my c++ code I have;

extern "C" { void foo_(float **, int &, int &); }

int main()
{
............
..............
int rows, columns;
float **array2d; // Now i need to pass this to the fortran code, the
allocation of the array and
// and filling it is done in the fortran code.
// How do i pass this to the fortran subroutine now, i did it this way

foo_(array2d, rows, columns);

// One more question, do i need to do the allocation and stuff here
again
// Do some stuff to manipulate with the array2d

return 0;

}

and my Fortran routine:

subroutine foo(arr,rows,columns)
integer rows, columns
real*8 ,allocatable:: arr (:,:)
! do some stuff to allocate the arrray and fil the stuff

end subroutine
Any help would be greatly appreciated

Regards
Sam

Jul 23 '05 #1
1 6191
Sam wrote:
I have a two dimensional array (the dimensions are not known)
that needs to be passed to Fortran from C++,
allocate the dimensions of the array in Fortran code,
do some filling up of the array in Fortran and then
accessing it in my C++ code.

Say in my C++ code I have;

extern "C" { void foo_(float **, int&, int&); }
Fortran won't know what to do with an array of pointers to float.
int main(int argc, char* argv[]) {
// ...
// ...
int rows, columns;
float **array2d; // Now I need to pass this to the Fortran code,
// the allocation of the array and filling it
// is done in the Fortran code.
// How do I pass this to the fortran subroutine now, I did it this way

foo_(array2d, rows, columns);

// One more question,
// "Do I need to do the allocation and stuff here again?"
// Do some stuff to manipulate with the array2d.

return 0;
}

and my Fortran routine:

subroutine foo(arr,rows,columns)
integer rows, columns
real*8 ,allocatable:: arr (:,:)
! Do some stuff to allocate the arrray and fill the stuff

end subroutine foo
Any help would be greatly appreciated
To do this,
you must pass a Fortran 90 pointer [to a 2D array]
to a Fortran 90 subroutine foo which allocates memory
for the 2D array and assigns a pointer to the array
to the pointer that you passed into subroutine foo.
Your C++ program must include f90_adapter.h
which contains an f90_2DPointer type definition
for a Fortran 90 2D array pointer (for Absoft in this case).
Function main(int, char**) invokes
function f90_2DPointerPointer(const f90_2DPointer*)
to retrieve the pointer to the beginning of the array
from the Fortran 90 pointer object.
cat foo.f90 subroutine foo(rows, columns, arr)
integer, intent(in):: rows, columns
integer:: row, column
double precision, pointer, dimension(:,:):: arr
double precision, pointer, dimension(:,:):: tmp
allocate(tmp(rows, columns))
do column = 1, columns
do row = 1, rows
tmp(row, column) = row + 10*column
end do
end do
arr => tmp
end subroutine foo
f90 -YEXT_NAMES=LCS -YEXT_SFX=_ -c foo.f90
cat f77_adapter.h #ifndef guard_f77_adapter_h
#define guard_f77_adapter_h

#include<stdint.h>
#include<stddef.h>
#include<string.h>

/*
* All Fortran 77 type names are of the form:
*
* f77_<type>
*
* where
*
* <type> in {subroutine, character, integer<size>, logical<size>,
* real_4, real_8, single, double, offset, length} and
* <size> in {, _1, _2, _4}.
*
* Note that the <size> parameter includes the empty string.
*/

typedef void f77_subroutine;

typedef char f77_character;

typedef int8_t f77_integer_1;
typedef int16_t f77_integer_2;
typedef int32_t f77_integer_4;
typedef f77_integer_4 f77_integer;

typedef uint8_t f77_logical_1;
typedef uint16_t f77_logical_2;
typedef uint32_t f77_logical_4;
typedef f77_logical_4 f77_logical;

typedef float f77_real_4;
typedef double f77_real_8;
typedef f77_real_4 f77_real;
typedef f77_real_4 f77_single;
typedef f77_real_8 f77_double;

typedef int f77_offset;
typedef size_t f77_length;

#endif/*guard_f77_adapter_h */
cat f90_adapter.h #ifndef guard_f90_adapter_h
#define guard_f90_adapter_h

#include<f77_adapter.h>

#ifdef __cplusplus
#define INLINE inline
#define STATIC
#define PRIVATE private:
#define PUBLIC public:
#else /*__cplusplus */
#define INLINE inline
#define STATIC static
#define PRIVATE
#define PUBLIC
#endif/*__cplusplus */

/*
* All Fortran 90 pointer type names are of the form:
*
* f90_<rank><type>Pointer
*
* where
*
* <rank> in {, 1D, 2D, 3D, 4D, 5D, 6D, 7D},
* <type> in {, single, double, integer<size>, logical<size>,
character}
* and
* <size> in {, _1, _2, _3, _4}.
*
* Note that all three parameters include the empty string.
*/

struct f90_Pointer; /* forward declaration */

#ifdef __cplusplus
extern "C" {
INLINE STATIC const
void* f90_PointerPointer(const struct f90_Pointer*);
}
#endif/*__cplusplus */

typedef struct f90_Pointer { /* generic scalar pointer */
PRIVATE
void* P[6];
#ifdef __cplusplus
public:
friend const void* f90_PointerPointer(const struct f90_Pointer*);
#endif/*__cplusplus */
} f90_Pointer;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC const
void* f90_PointerPointer(const f90_Pointer* p) {
return p->P[0]; }
#ifdef __cplusplus
}
#endif/*__cplusplus */

struct f90_triplet; /* forward declaration */

#ifdef __cplusplus
extern "C" {
INLINE STATIC
size_t f90_tripletExtent(const struct f90_triplet*);
INLINE STATIC
ptrdiff_t f90_tripletStride(const struct f90_triplet*);
}
#endif/*__cplusplus */

typedef struct f90_triplet {
PRIVATE
f77_integer lbound;
f77_integer ubound;
f77_integer stride;
#ifdef __cplusplus
public:
friend size_t f90_tripletExtent(const struct f90_triplet*);
friend ptrdiff_t f90_tripletStride(const struct f90_triplet*);
#endif/*__cplusplus */
} f90_triplet;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC
size_t f90_tripletExtent(const f90_triplet* p) {
return (p->lbound < p->ubound)? (p->ubound - p->lbound + 1):
(p->lbound - p->ubound + 1); }

INLINE STATIC
ptrdiff_t f90_tripletStride(const f90_triplet* p) {
return p->stride; }
#ifdef __cplusplus
}
#endif/*__cplusplus */

struct f90_1DPointer; /* forward declaration */

#ifdef __cplusplus
extern "C" {
INLINE STATIC const
void* f90_1DPointerPointer(const struct f90_1DPointer*);
INLINE STATIC
size_t f90_1DPointerExtent1(const struct f90_1DPointer*);
INLINE STATIC
ptrdiff_t f90_1DPointerStride1(const struct f90_1DPointer*);
}
#endif/*__cplusplus */

typedef struct f90_1DPointer { /* generic 1D array pointer */
PRIVATE
void* P[6];
f90_triplet T[1];
#ifdef __cplusplus
public:
friend const void* f90_1DPointerPointer(const struct f90_1DPointer*);
friend size_t f90_1DPointerExtent1(const struct f90_1DPointer*);
friend ptrdiff_t f90_1DPointerStride1(const struct f90_1DPointer*);
#endif/*__cplusplus */
} f90_1DPointer;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC const
void* f90_1DPointerPointer(const f90_1DPointer* p) {
return p->P[0]; }

INLINE STATIC
size_t f90_1DPointerExtent1(const f90_1DPointer* p) {
return f90_tripletExtent(&(p->T[0])); }

INLINE STATIC
ptrdiff_t f90_1DPointerStride1(const f90_1DPointer* p) {
return f90_tripletStride(&(p->T[0])); }
#ifdef __cplusplus
}
#endif/*__cplusplus */

struct f90_2DPointer; /* forward declaration */

#ifdef __cplusplus
extern "C" {
INLINE STATIC const
void* f90_2DPointerPointer(const struct f90_2DPointer*);
INLINE STATIC
size_t f90_2DPointerExtent1(const struct f90_2DPointer*);
INLINE STATIC
ptrdiff_t f90_2DPointerStride1(const struct f90_2DPointer*);
INLINE STATIC
size_t f90_2DPointerExtent2(const struct f90_2DPointer*);
INLINE STATIC
ptrdiff_t f90_2DPointerStride2(const struct f90_2DPointer*);
}
#endif/*__cplusplus */

typedef struct f90_2DPointer { /* generic 2D array pointer */
PRIVATE
void* P[6];
f90_triplet T[2];
#ifdef __cplusplus
public:
friend const void* f90_2DPointerPointer(const struct f90_2DPointer*);
friend size_t f90_2DPointerExtent1(const struct f90_2DPointer*);
friend ptrdiff_t f90_2DPointerStride1(const struct f90_2DPointer*);
friend size_t f90_2DPointerExtent2(const struct f90_2DPointer*);
friend ptrdiff_t f90_2DPointerStride2(const struct f90_2DPointer*);
#endif/*__cplusplus */
} f90_2DPointer;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC const
void* f90_2DPointerPointer(const f90_2DPointer* p) {
return p->P[0]; }

INLINE STATIC
size_t f90_2DPointerExtent1(const f90_2DPointer* p) {
return f90_tripletExtent(&(p->T[0])); }

INLINE STATIC
ptrdiff_t f90_2DPointerStride1(const f90_2DPointer* p) {
return f90_tripletStride(&(p->T[0])); }

INLINE STATIC
size_t f90_2DPointerExtent2(const f90_2DPointer* p) {
return f90_tripletExtent(&(p->T[1])); }

INLINE STATIC
ptrdiff_t f90_2DPointerStride2(const f90_2DPointer* p) {
return f90_tripletStride(&(p->T[1])); }
#ifdef __cplusplus
}
#endif/*__cplusplus */

struct f90_characterPointer; /* forward declaration */

#ifdef __cplusplus
extern "C" {
INLINE STATIC const
char* f90_characterPointerPointer(
const struct f90_characterPointer*);
INLINE STATIC
size_t f90_characterPointerLength(
const struct f90_characterPointer*);
}
#endif/*__cplusplus */

typedef struct f90_characterPointer { /* character string scalar
pointer */
PRIVATE
char* P[6];
#ifdef __cplusplus
public:
friend const char* f90_characterPointerPointer(
const struct f90_characterPointer*);
friend size_t f90_characterPointerLength(
const struct f90_characterPointer*);
#endif/*__cplusplus */
} f90_characterPointer;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC const
char* f90_characterPointerPointer(const f90_characterPointer*
p) {
return p->P[0]; }

INLINE STATIC
size_t f90_characterPointerLength(const f90_characterPointer* p) {
return (size_t)p->P[1]; }
#ifdef __cplusplus
}
#endif/*__cplusplus */

struct f90_1DcharacterPointer; /* forward de3claration */
#ifdef __cplusplus
extern "C" {
INLINE STATIC const
char* f90_1DcharacterPointerPointer(const
f90_1DcharacterPointer*);

INLINE STATIC
size_t f90_1DcharacterPointerExtent1(const
f90_1DcharacterPointer*);

INLINE STATIC
ptrdiff_t f90_1DcharacterPointerStride1(const
f90_1DcharacterPointer*);

INLINE STATIC
size_t f90_1DcharacterPointerLength(const
f90_1DcharacterPointer*);
}
#endif/*__cplusplus */

typedef struct f90_1DcharacterPointer {/* 1D character string array
pointer*/
PRIVATE
char* P[6];
f90_triplet T[1];
#ifdef __cplusplus
public:
friend const char* f90_1DcharacterPointerPointer(
const struct f90_1DcharacterPointer*);
friend size_t f90_1DcharacterPointerExtent1(
const struct f90_1DcharacterPointer*);
friend ptrdiff_t f90_1DcharacterPointerStride1(
const struct f90_1DcharacterPointer*);
friend size_t f90_1DcharacterPointerLength(
const struct f90_1DcharacterPointer*);
#endif/*__cplusplus */
} f90_1DcharacterPointer;

#ifdef __cplusplus
extern "C" {
#endif/*__cplusplus */
INLINE STATIC const
char* f90_1DcharacterPointerPointer(const
f90_1DcharacterPointer* p) { return p->P[0]; }

INLINE STATIC
size_t f90_1DcharacterPointerExtent1(const
f90_1DcharacterPointer* p) { return f90_tripletExtent(&(p->T[0])); }

INLINE STATIC
ptrdiff_t f90_1DcharacterPointerStride1(const
f90_1DcharacterPointer* p) { return f90_tripletStride(&(p->T[0])); }

INLINE STATIC
size_t f90_1DcharacterPointerLength(const
f90_1DcharacterPointer* p) {
return (size_t)p->P[2]; }
#ifdef __cplusplus
}
#endif/*__cplusplus */

#undef PRIVATE
#undef PUBLIC
#undef STATIC
#undef INLINE

#endif/*guard_f90_adapter_h */
cat main.cc #include <iostream>
#include <f90_adapter.h>

extern "C" {
f77_subroutine foo_(
const
f77_integer&, // rows
const
f77_integer&, // columns
f90_2DPointer& // 2D array
);
}
int main(int argc, char* argv[]) {
const
f77_integer rows = 3;
const
f77_integer columns = 5;
f90_2DPointer arr;
foo_(columns, rows, arr);
f77_double* A = (f77_double*)f90_2DPointerPointer(&arr);
for (f77_integer row = 0; row < rows; ++row) {
for (f77_integer column = 0; column < columns; ++column) {
std::cout << ' ' << A[row*columns + column];
}
std::cout << std::endl;
}

return 0;
}
g++ -I. -L/opt/absoft/lib -Wall -ansi -pedantic \ -o main main.cc foo.o -lfio -lf77math ./main

11 12 13 14 15
21 22 23 24 25
31 32 33 34 35
Jul 23 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: NM | last post by:
Hello all, I am supposed to do some mixed programming with c++ and fortran. I was succeeful in exchanging the 2D arrays from fortran to c++ and...
2
by: Jonathan Underwood | last post by:
Hi I have a 2 dimensional array allocated as a contiguous chunk of memory, as described in Question 6.16 in the FAQ (i.e. in the manner of array...
10
by: Pete | last post by:
Can someone please help, I'm trying to pass an array to a function, do some operation on that array, then return it for further use. The errors I am...
3
by: Alex Munk | last post by:
I would like to be able to pass a 2-dimensional array to a function as a string parameter. In the called function I would like to be able to convert...
3
by: SQLScott | last post by:
I have looked all over and I cannot find an example or information on passing a multi-dimensional array. Well, that is not true. I found a close...
4
by: entitledX | last post by:
Hi, I'm trying to use the HDF library to read a few HDF files that I need to process. The data in each file varies in rows, but the columns...
2
by: nleahcim | last post by:
Hi - I am working on writing a number of matrix manipulation functions. The most basic one was a printing algorithm - and it shows the problem I'm...
272
by: Peter Olcott | last post by:
http://groups.google.com/group/comp.lang.c++/msg/a9092f0f6c9bf13a I think that the operator() member function does not work correctly, does...
2
by: luis | last post by:
I'm using ctypes to call a fortran dll from python. I have no problems passing integer and double arryas, but I have an error with str arrys. For...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
0
jalbright99669
by: jalbright99669 | last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...
0
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand....
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.