473,387 Members | 1,834 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 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 6366
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 the other way, but was unable to that same with...
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 2 on the page...
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 getting for the following code are, differences...
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 the string back into a 2-dimensional array....
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 example in C++ but it didn't work when I...
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 remain constant. Because of that, I had dynamically...
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 having. I'm passing it a pointer a mutidimensional...
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 anyone else know how to make a template for making two...
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 example: ..... StringVector = c_char_p *...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.