|
| View previous topic :: View next topic |
| Author |
Message |
dab143
Joined: 28 Nov 2004 Posts: 4
|
Posted: Sun Nov 28, 2004 6:54 pm Post subject: Pass declared var types: F90 to C |
|
|
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:
| Code: |
! =================================
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:
| Code: |
#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:
| Code: |
pgcc -c testc.c
pgf90 test.f90 testc.o -o test
|
Finally, the output looks like this:
| Code: |
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] |
|
| Back to top |
|
 |
mkcolg
Joined: 30 Jun 2004 Posts: 4996 Location: The Portland Group Inc.
|
Posted: Mon Nov 29, 2004 5:17 pm Post subject: |
|
|
Hi David,
You need to account for the Fortran descriptor and put some padding in your C structs.
Your testc.c should be changed to the following.
| Code: | #include <stdlib.h>
#ifdef __x86_64__
#define DESC_LEN 19
#else
#define DESC_LEN 17
#endif
typedef struct
{
double x;
double y;
} gen_vertex;
typedef struct
{
int num_vertices;
gen_vertex *vertex;
int v_desc[DESC_LEN];
} gen_vertex_list;
typedef struct
{
int num_contours;
int *hole;
int h_desc[DESC_LEN];
gen_vertex_list *contour;
int c_desc[DESC_LEN];
} gen_polygon;
|
While this will work for this case, it is definately not portable. Also note that the descriptor length may change with each new release of the compiler. I determined the descriptor length by running a.out in pgdbg and printing spoly.
- Mat |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2002 phpBB Group
|