C++ Fortran mixed programming

N

NM

Hello All
I am writing some progam that involves both C++ and Fortran. Some of the
existing code is in Fortran. The main program will be in C++ and it will
call some Fortran subroutine. All the memory allocation has to be done in
C++.

For arrays of structures and arrays (including multi-dimensional array) of
primitive data types declared in Fortran, I know the corresponding data
structures in C++. So I can declare those data structures in C++, allocate
them, and pass them as argument to Fortran subroutine. But when a member of
the structure is a pointer (declared in Fortran), I cannot figure out what
should be the corresponding data structures in C++. I have tried pointer to
the same type in C++, but it do not work and the Fortran subroutine will get
a segmentation fault when accessing the pointer.

I cannot change the data structures defined in Fortran. What I can do is to
use appropiate data structures in C++ and pass it to the Fortran subroutine
as argument.
Can anyone tell me what should be the data structure defined in C++ that
corresponds to the Fortran structure "node". Thanks in advance.

Here is my example fortran code

subroutine test_fortran_sub(NODES,MAXNODS)
c
implicit none

type node
integer :: order
double precision,dimension:)),pointer :: zdofs
end type node

integer :: MAXNODS
type(node) :: NODES(MAXNODS)

integer :: i,j,k

write(*,*) 'MAXNODS = ',MAXNODS
do i=1,MAXNODS
NODES(i)%order = i
do j = 1,5
NODES(i)%zdofs(j) = i+j
enddo
enddo

return
end


and Here is the example C++ code

#include <iostream>
using namespace std;

class node_struct {
public:
int order;
double *zdofs;
};

typedef node_struct *node;

extern "C" {
void test_fortran_sub_(node NODES,int *MAXNODS);
}

int main(void)
{
int MAXNODS = 1;
node NODES;

NODES = new node_struct[MAXNODS];

for (int i = 0; i < MAXNODS; i++ ) {
NODES.zdofs = new double[5];
}

test_fortran_sub_(NODES,&MAXNODS);

for (int i = 0; i < MAXNODS; i++) {
cout << "NODES[" << i << "].order = " << NODES.order << endl;
for (int j = 0; j < 5; j++)
cout << "NODES[" << i << "].zdofs["<<j<<"] = " << NODES.zdofs[j] <<
endl;
}
return 0;
}
 
R

Richard Maine

NM said:
But when a member of
the structure is a pointer (declared in Fortran), I cannot figure out what
should be the corresponding data structures in C++. I have tried pointer to
the same type in C++,

There is no direct correspondence between C/C++ pointers and Fortran ones.
There are vendor-specific solutions, but nothing portable until the C
interop stuff of Fortran 2003 (which some vendors are already
incorporating into their f95 compilers).

Except for scalars (which isn't what you have), it is pretty much guaranteed
not to look like a pointer to the corresponding type in C/C++. That's
because the Fortran pointer needs to store extra information about the
bounds; that information has to go somewhere, and the C/C++ pointer
doesn't have room for it.
Can anyone tell me what should be the data structure defined in C++ that
corresponds to the Fortran structure "node". Thanks in advance.

See your vendor's manuals for a vendor-specific answer. It *DOES*
vary among vendors. If your vendor doesn't document it (some do),
you can probably reverse engineer it, but be aware that the answer
will only be valid for that particular vendor.
 
E

E. Robert Tisdale

NM said:
I am writing some progam that involves both C++ and Fortran.
Some of the existing code is in Fortran.
The main program will be in C++ and it will call some Fortran subroutine.
All the memory allocation has to be done in C++.

For arrays of structures and arrays (including multi-dimensional array)
of primitive data types declared in Fortran,
I know [that] the corresponding data structures in C++.
So I can declare those data structures in C++, allocate them,
and pass them as argument to Fortran subroutine.
But when a member of the structure is a pointer (declared in Fortran),
I cannot figure out what should be the corresponding data structures in C++.
I have tried pointer to the same type in C++,
but it do not work and the Fortran subroutine
will get a segmentation fault when accessing the pointer.
I cannot change the data structures defined in Fortran.
What I can do is to use appropiate data structures in C++
and pass it to the Fortran subroutine as argument.
Can anyone tell me what should be the data structure defined in C++
that corresponds to the Fortran structure "node".

Here is my example fortran code

subroutine test_fortran_sub(NODES, MAXNODS)
c
implicit none

type node
integer:: order
double precision, dimension:)), pointer:: zdofs
end type node

integer:: MAXNODS
type (node):: NODES(MAXNODS)

integer:: i, j, k

write(*, *) 'MAXNODS = ', MAXNODS
do i = 1, MAXNODS
NODES(i)%order = i
do j = 1, 5
NODES(i)%zdofs(j) = i + j
enddo
enddo

return
end


and Here is the example C++ code

#include <iostream>
// using namespace std;
#include said:
class node_struct {
public:
//int order;
//double *zdofs;
f77_integer order;
f90_1DPointer data;
};

typedef node_struct *node;

extern "C" {
f77_subroutine test_fortran_sub_(node, f77_integer*);
f77_subroutine initializenode(node, f77_integer*);
}

int main(void) {
using namespace std;
int MAXNODS = 1;
node* NODES;

NODES = new node_struct[MAXNODS];

for (int i = 0; i < MAXNODS; ++i) {
//NODES.zdofs = new double[5];

const int size = 5;
f77_initializenode(&(NODE), &size);
// use Fortran 90 to allocate storage
}

test_fortran_sub_(NODES, &MAXNODS);

for (int i = 0; i < MAXNODS; ++i) {
cout << "NODES[" << i << "].order = " << NODES.order << endl;

double* zdofs
= (double*)f90_PointerPointer(&(NODES.data));
for (int j = 0; j < 5; ++j) {
cout << "NODES[" << i << "].zdofs[" << j << "] = "
<< NODES.zdofs[j] << endl; }
}
return 0;
}


The f77_adapter.h and f90_adapter.h header files are platform dependent.
Tell me which machine architecture, operating system and Fortran 90
compiler you are using and I'll try to sent you the right ones.
 
P

Pierre Asselin

In comp.lang.fortran NM said:
I am writing some progam that involves both C++ and Fortran. Some of the
existing code is in Fortran. The main program will be in C++ and it will
call some Fortran subroutine. All the memory allocation has to be done in
C++.
For arrays of structures and arrays (including multi-dimensional array) of
primitive data types declared in Fortran, I know the corresponding data
structures in C++.

Even that is compiler dependent (until the C interop features of
F2003 become available). You may also have more trouble mixing
Fortran and C++ than Fortran and C. Both C++ and Fortran need to
do some serious initialization at startup before transferring
control to your C++ main(). Will the Fortran runtime be initialized
properly? Maybe, but that's another set of system dependencies for
you to worry about.

[ ... ] But when a member of
the structure is a pointer (declared in Fortran), I cannot figure out what
should be the corresponding data structures in C++.

That's even less portable. Fortran pointers don't correspond to C++
pointers in any simple way.

If I were you, I would
1) write accessors in Fortran, callable from C,
and declare them as "extern C" on the C++ side;
2) do all the I/O on the C++ side to reduce the risk initialization
conflicts in the two runtime environments.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top