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