Bind(c) for procedures with complicated derived types

John McFarland john.mcfarland@swri.org
Wed Jun 3 22:00:00 GMT 2009


Tobias Burnus wrote:
> John McFarland wrote:
>> Unfortunately I may not have been super-clear in my first message, so
>> I feel like we're going around in circles a little bit.  I am not
>> asking *how* we can use opaque containers or *if* it is possible to
>> use them, because we already do.
> 
> How about the following:
> 
> ------------------------------------------------
> int object_size();
> void init_object(void*object, int*n, double*val);
> void print_object(void*object);
> 
> 
> int main(void) {
>   int osize;
>   osize = object_size();
>   // How many floats do we need?
>   float dum;
>   osize = osize / sizeof(dum) + 1;
> 
> 
>   // Declare the opaque container
>   float object[osize];
> 
> 
>   int n=2;
>   double val=2.0;
>   init_object(object, &n, &val);
>   print_object(object);
> }
> ------------------------------------------------
> 
> ------------------------------------------------
> MODULE fmod
>   use iso_c_binding
>   implicit none
>   TYPE Object
>     REAL*8, POINTER :: x(:)
>   END TYPE Object
> 
> 
> CONTAINS
> 
>   FUNCTION object_size() RESULT(osize) bind(C)
>     INTEGER(c_int) :: osize
>     TYPE (Object) :: o
>     osize = c_sizeof(o)
>   END FUNCTION object_size
> 
> 
>   SUBROUTINE init_object(co,n,val) bind(C)
>     type(c_ptr) :: co
>     INTEGER(c_int), INTENT(in) :: n
>     TYPE (Object), pointer :: o
>     REAL(c_double), INTENT(in) :: val
>     call c_f_pointer(co,o)
>     ALLOCATE( o%x(n) )
>     o%x = val
>   END SUBROUTINE init_object
> 
> 
>   SUBROUTINE print_object(co) bind(C)
>     type(c_ptr) :: co
>     TYPE (Object),pointer :: o
>     PRINT*, o%x
>   END SUBROUTINE print_object
> END MODULE fmod
> ------------------------------------------------

Nice example, that did not occur to me.  That certainly gets around the 
BIND(C) and the name-mangling, but unfortunately it's not a practical 
solution for our project.  Our project is fairly large, and it has many 
subroutines we want to interface with, so we are looking for a solution 
that does not require us to modify all of our subroutines.  Further, we 
spend almost all of our development time in Fortran.  Modules like fmod 
in the above example are written primarily to be USE'd by other Fortran 
code, so we would prefer clean Fortran and slightly messy C to clean C 
and messy Fortran (messy Fortran in the sense that every time we create 
a new function in Fortran we have to convert from a C pointer to the 
Fortran derived type that we want to operate on; and then also we would 
be passing around C pointer derived types in Fortran when we could be 
passing around our "native" derived types -- gets very messy, and begs 
the question again of why write the program in Fortran).

So I would rephrase my question again as: with the working code example 
I showed previously, is there any way to have the compiler write the 
name of the function "init_object" as "init_object" instead of 
"__fmod_MOD_init_object", without modifying the subroutines (we don't 
mind adding BIND(C), but since the subroutines must accept derived types 
that are not themselves "interoperable", it doesn't seem like an option 
with gfortran)?

John



More information about the Fortran mailing list