Bind(c) for procedures with complicated derived types

Dennis Wassel dennis.wassel@googlemail.com
Wed Jun 3 15:47:00 GMT 2009


Hi John,

2009/6/3 John McFarland <john.mcfarland@swri.org>:
> We have a large project that makes extensive use of complicated derived
> types (i.e. they contain pointer arrays, allocatable arrays, other derived
> types, etc).  We can currently use the functions and subroutines that
> operate on these derived types from C code, without any use of BIND(C), by
> making use of opaque containers; that is, the C prototype just has void*
> where the derived type argument is, and we pass around some chunk of memory
> (maybe an array of floats) that is big enough to contain the Fortran type.
>  This acts like a handle to the derived type and allows us to call all of
> its functions from C code.

I tried going down that road once, but my experience is that this will
bite you some day. Good for you if it hasn't so far!
(I could never get this construction to run from a C main, for
instance, because the pointer and allocatable components want to be
"initialised" instead of just having memory to write into)

> However, we now want to go through and add BIND(C) to all of our
> subroutines, so that we can get particular symbol names in the symbol table,
> as opposed to __modname_MOD_funcname (which aside from being ugly in C, is
> compiler-dependent).  The problem is gfortran gives an error stating that
> the derived type argument must be interoperable, but I can't add BIND(C) to
> the derived type declarations because they contain non-primitive data.
>  Below is an example that shows the type of code I am trying to compile
> (this example will compile with g95):
>
> MODULE mod
>  TYPE Structure
>    INTEGER, POINTER :: x(:)
>  END TYPE Structure
> CONTAINS
>  SUBROUTINE sub(s) BIND(C)
>    TYPE (Structure) :: s
>    ! Do something with s
>  END SUBROUTINE sub
> END MODULE mod

I'd consider this as a bug rather than a feature of g95.
The background is that in memory, the pointer component will be a
compiler-dependent array descriptor that holds type, stride and extent
information, rather than just a C pointer. If you know this structure,
you can access it from C, but (for the time being) the companion C
compilers don't have a clue about Fortran array descriptors. Fortran
2008 will define headers and macros to overcome that limitation.
If you want to take this path, there is the chasm interop API, which
hides this complexity from you for a limited number of compilers. Be
warned, though, that this is version-, compiler- and maybe even
platform-specific.

> Is there any way in gfortran to inhibit the compiler error and allow the
> program to compile?  If not, this seems like a limitation because the
> "opaque container" approach is a very powerful way of interfacing with C
> without defining "interoperable" derived types.

If you ask me, the opaque container approach is yet another glorious
way to Shoot Yourself In The Foot (TM) with C, but you certainly have
a right to your own opinion! :-)

I know of know way to inhibit these (justified!) error messages, see above.

The other possible path to take is to make your Fortran structures
C-interoperable. I went down this (admittedly ugly) path, because I
could not wait until compiler support for Fortran 2008 was widely
available. Technically, you "just" replace all non-interoperable
things with C_PTR and use the C_F_POINTER intrinsic for the Fortran
parts. This is ugly, but it works.

Cheers,
Dennis



More information about the Fortran mailing list