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 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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
by: antdb |
last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine
In the overall architecture, a new "hyper-convergence" concept was...
|
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...
|
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...
|
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...
|
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....
|
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...
|
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...
| |