I’ve read Chapters 9 and 10 of the PGI User’s Manual as well as lots of other web sites on calling C from Fortran but still can’t solve my particular problem of passing a declared variable type from Fortran 90 to C. The declared variable type also contains several pointers, which may be contributing to my problem.
I tried adding the SEQUENCE parameter to the declared variable, but that didn’t seem to make a difference. As shown below, the major symptom appears to be that not all of the pointer addresses make it through to the C function.
The Fortran 90 main code looks like this:
! =================================
PROGRAM test
! =================================
integer,parameter :: rd = SELECTED_REAL_KIND(p=12,r=37)
TYPE :: gen_vertex
SEQUENCE
real(kind=rd) :: x
real(kind=rd) :: y
END TYPE gen_vertex
TYPE :: gen_vertex_list
SEQUENCE
integer :: num_vertices
type(gen_vertex),pointer,dimension(:) :: vertex
END TYPE gen_vertex_list
TYPE :: gen_polygon
SEQUENCE
integer :: num_contours
integer,pointer,dimension (:) :: hole
type(gen_vertex_list),pointer,dimension (:) :: contour
END TYPE gen_polygon
TYPE(gen_polygon) :: spoly
! DEFINE POLYGON
spoly%num_contours = 2
allocate(spoly%hole(spoly%num_contours))
allocate(spoly%contour(spoly%num_contours))
spoly%hole(1) = 1
spoly%contour(1)%num_vertices = 3
allocate(spoly%contour(1)%vertex(spoly%contour(1)%num_vertices))
spoly%contour(1)%vertex(1)%x = 0.0d0
spoly%contour(1)%vertex(1)%y = 0.0d0
spoly%contour(1)%vertex(2)%x = 1.0d0
spoly%contour(1)%vertex(2)%y = 0.0d0
spoly%contour(1)%vertex(3)%x = 1.0d0
spoly%contour(1)%vertex(3)%y = 1.0d0
spoly%hole(2) = 0
spoly%contour(2)%num_vertices = 3
allocate(spoly%contour(2)%vertex(spoly%contour(2)%num_vertices))
spoly%contour(2)%vertex(1)%x = 0.0d0
spoly%contour(2)%vertex(1)%y = 0.0d0
spoly%contour(2)%vertex(2)%x = 2.0d0
spoly%contour(2)%vertex(2)%y = 0.0d0
spoly%contour(2)%vertex(3)%x = 2.0d0
spoly%contour(2)%vertex(3)%y = 2.0d0
! CALL GPC (THE SCENIC ROUTE)
call gen_test( spoly )
END PROGRAM test
The C routine looks like this:
#include <stdlib.h>
typedef struct
{
double x;
double y;
} gen_vertex;
typedef struct
{
int num_vertices;
gen_vertex *vertex;
} gen_vertex_list;
typedef struct
{
int num_contours;
int *hole;
gen_vertex_list *contour;
} gen_polygon;
void gen_test_(gen_polygon *subj )
{
int i,j;
printf("\n output from the C routine\n");
printf(" address of subj = %p\n",subj );
printf(" address of subj->hole = %p\n",subj->hole );
printf(" address of subj->contour = %p\n",subj->contour );
printf(" num_contours = %d\n",subj->num_contours );
for (i=0; i < subj->num_contours; i++) {
printf(" num_vertices = %d\n",subj->contour[i].num_vertices );
printf(" hole = %d\n",subj->hole[i] );
for (j=0; j < subj->contour[i].num_vertices; j++) {
printf(" vertex[%d].x = %f\n",j,subj->contour[i].vertex[j].x );
printf(" vertex[%d].y = %f\n",j,subj->contour[i].vertex[j].y );
}
}
return;
}
The compilation (using version 5.2-1 for both pgf90 and pgcc) looks like this:
pgcc -c testc.c
pgf90 test.f90 testc.o -o test
Finally, the output looks like this:
output from the C routine
address of subj = 0x520b30
address of subj->hole = 0x524850
address of subj->contour = (nil)
num_contours = 2
Segmentation fault
Any help — either specific or generally relating to passing declared variable types and/or pointers from Fortran90 to C — would be greatly appreciated. I similarly struggled with a different approach where I tried to pass just one pointer to an integer array to a C routine, free and re-allocate the pointer within the C routine, and then pass it back, so if anyone can suggest further reading on passing pointers back and forth between Fortran90 and C, that would be great too!
Sorry for the long post!
David
[/code]