Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29285 Discussions

INTERFACE Needed to Communicate from Fortran to C Subroutine w/ 'typedef struct'

Krob__Jeff
Beginner
449 Views

All,

Been working for a while having 'fun' trying to port the General Polygon Clipper (GPC) Library from C to Fortran but decided it may be easier to just to call the 2-3 GPC 'C' routines I need from my Fortran code. All the polygon info is contained in 'typedef struct's in the C code which are as follows:

*********************************************************************************

typedef enum                        /* Set operation type                */
{
  GPC_DIFF,                         /* Difference                        */
  GPC_INT,                          /* Intersection                      */
  GPC_XOR,                          /* Exclusive or                      */
  GPC_UNION                         /* Union                             */
} gpc_op;

typedef struct                      /* Polygon vertex structure          */
{
  double              x;            /* Vertex x component                */
  double              y;            /* vertex y component                */
} gpc_vertex;

typedef struct                      /* Vertex list structure             */
{
  int                 num_vertices; /* Number of vertices in list        */
  gpc_vertex         *vertex;       /* Vertex array pointer              */
} gpc_vertex_list;

typedef struct                      /* Polygon set structure             */
{
  int                 num_contours; /* Number of contours in polygon     */
  int                *hole;         /* Hole / external contour flags     */
  gpc_vertex_list    *contour;      /* Contour array pointer             */
} gpc_polygon;

*********************************************************************************

The prototypes of the 3 GPC routines I need to communicate with are:

void gpc_add_contour         (gpc_polygon     *polygon,
                              gpc_vertex_list *contour,
                              int              hole);

void gpc_polygon_clip        (gpc_op           set_operation,
                              gpc_polygon     *subject_polygon,
                              gpc_polygon     *clip_polygon,
                              gpc_polygon     *result_polygon);

void gpc_free_tristrip       (gpc_tristrip    *tristrip);

On the Fortran side, my equivalent Derived Types are:

  TYPE :: gpc_op                                    !   /* Set operation type                */
    INTEGER :: GPC_DIFF=0                            !    /* Difference                        */
    INTEGER :: GPC_INT=1                            !    /* Intersection                      */
    INTEGER :: GPC_XOR=2    !***not used            !    /* Exclusive or                      */
    INTEGER :: GPC_UNION=3                            !    /* Union                             */
  END TYPE

  TYPE :: GPC_VERTEX                    !    /* Polygon vertex structure          */
    REAL(8) :: x                                    !    /* Vertex x component                */
    REAL(8) :: y                                    !    /* vertex y component                */
  END TYPE

  TYPE :: GPC_VERTEX_LIST                !    /* Vertex list structure             */
    INTEGER :: num_vertices                            !    /* Number of vertices in list        */
    TYPE (GPC_VERTEX),ALLOCATABLE :: vertex(:)        !    /* Vertex array pointer              */
  END TYPE

  TYPE :: GPC_POLYGON                         !    /* Polygon set structure             */
    INTEGER :: num_contours                            !    /* Number of contours in polygon     */
    INTEGER :: hole            ! added                    !    /* Hole / external contour flags     */
    INTEGER,ALLOCATABLE :: holea(:)       ! changed        !    /* Hole / external contour flags     */
    TYPE (GPC_VERTEX_LIST),ALLOCATABLE :: contour(:)    !    /* Contour array pointer             */
  END TYPE

**********************************************************************************************

Now, I have ZERO experience (and have found no references or examples) as to how the INTERFACE would be constructed to exchange data between Fortran & C structures. For example...the Fortran subroutine cgr_polydiff calls gpc_polygon_clip in the following way:

SUBROUTINE cgr_polydiff(npin0,xin0,yin0,npin1,xin1,yin1,maxnpo,npo,xo,yo,iret)
! --------------------------------------------------
!/************************************************************************
! * cgr_polydiff                             *
! *                                    *
! * This function computes the difference of two polygons using the      *
! * difference clipping option in the GPC (General Polygon Clipper)      *
! * library.  The area that is in polygon 0 but not in polygon 1 is     *
! * returned.                                *
! *                                    *

! * Input parameters:                            *
! * *npin0            int     Number of points in polygon 0               *
! * *xin0             float   X coordinates of polygon 0                  *
! * *yin0             float   Y coordinates of polygon 0                  *
! * *npin1            int     Number of points in polygon 1               *
! * *xin1             float   X coordinates of polygon 1                  *
! * *yin1             float   Y coordinates of polygon 1                  *
! * *maxnpo           int     Maximum number of output points        *
! *                                    *
! * Output parameters:                            *
! * *npo              int     Number of points in output polygon          *
! * *xo               float   X coordinates of output polygon             *
! * *yo               float   Y coordinates of output polygon             *
! * *iret             int     Return code                    *
! *                    =  1 - no area in 0 that isn't in 1        *
! *                 = -1 - insufficient maxnpo            *
! *                 = -2 - polygons have insufficient # of pts    *
! *                                    *
! **                                    *

USE GPC

! - - - arg types - - -
  INTEGER :: npin0,npin1,iret                                                
  INTEGER :: maxnpo,npo                                                      
  REAL(4) :: xin0,yin0                                                     
  REAL(4) :: xin1,yin1                                                     
  REAL(4) :: xo,yo                                                       
! - - - local declarations - - -
  INTEGER :: ii,hole,ier
  TYPE(GPC_POLYGON) :: gpc_poly_0
  TYPE(GPC_POLYGON) :: gpc_poly_1
  TYPE(GPC_POLYGON) :: gpc_diff_poly
  TYPE(GPC_VERTEX_LIST) :: verts
! - - - begin - - -

< - snip - >

  CALL gpc_polygon_clip( GPC_DIFF, gpc_poly_0, gpc_poly_1, gpc_diff_poly )

*************************************************************************************

Using Intel® Parallel Studio XE 2015 Composer Edition for Fortran Windows, how would the INTERFACE be constructed to handle this example?

Thanks in advance,

Jeff

 

 

 

 

 

0 Kudos
1 Reply
Steven_L_Intel1
Employee
449 Views

I can tell you that you do NOT want to use ALLOCATABLE or DIMENSION(:) in your Fortran derived types. These do not correspond to what's on the C side. Most likely you want TYPE(C_PTR) there and assign the values using C_LOC. Also note where the C struct definition has a "*" - this indicates it wants a pointer not the actual value. For example "hole" in gpc_polygon. So again you would declare the Fortran type with TYPE(C_PTR).

0 Kudos
Reply