C struct member : pointer to double (Fortran-C interop.)

Hello,

Considered the severe lacking of a mature and complete Fortran NURBS library, I’m trying to create an interface to the SISL NURBS (C language ) for Fortran. I’ve several doubts, but maybe it’s better to tackle one of them at a time.
For now, this is a struct I’m trying to interoperate with :

typedef struct SISLdir
{
  int igtpi;			/* 0 - The direction of the surface or curve
			               is not greater than pi in any
			               parameter direction.
			           1 - The direction of the surface or curve
			               is greater than pi in the first
			               parameter direction.
			           2 - The direction of the surface is greater
			               than pi in the second parameter
			               direction. 			     */
  double *ecoef;		/* The coordinates to the center of the cone.*/
  double aang;			/* The angle from the center whice describe the
			           cone.				     */
  double *esmooth;		/* Coordinates of object after smoothing.    */
} SISLdir;

This is the Fortran module with the struct interface:

module mod_sislfor

use iso_c_binding
implicit none

private 
public ::  sisldir 

!-------------------------------------

! interoperability with struct SISLdir

!------------------------------------

type, bind(c) :: sisldir

  integer (c_int) :: igtpi

  real(c_double):: ecoef(*)

  real(c_double):: aang

  real(c_double):: esmooth(*)

end type sisldir


end module mod_sislfor

I’m in doubt about how to treat the struct member double *esmooth and double *ecoef . Do you have some suggestions ?
Thanks

I believe they need to be type(c_ptr). I have a sneaking suspicion that they are pointers because the consuming code is going to use them kind of like arrays. You’ll need to be careful about allocating/deallocating the memory, and storing/retrieving the values from them. Probably you’ll need some extra C code to do that properly.

1 Like

Yes, as @everythingfunctional said, you will need to define everything with a star (or several stars) like this:

type(c_ptr) :: ecoef
type(c_ptr) :: esmooth

Here they seem to point toward arrays containing coordinates (but we can’t see if it’s 2D or 3D). You will need to read the C source code to be sure.
Note that in Fortran, there is some kind of loss of information since when you write type(c_ptr) :: ecoef you don’t even see that it’s pointers toward double. Just pointers… Therefore, adding comments seems a good practice…
And yes, if the library does not offer some functions to free those arrays, it’s another problem.

1 Like

If you try to compile your module, you will find it is not conforming syntax - the compiler will issue erros.

As mentioned by @everythingfunctional , if you attempt a direct Fortran interface, you will require type(c_ptr), say type(c_ptr) :: p_ecoef. And your Fortran code will need to use c_f_pointer to generate Fortran entities of double type for ecoef.

That is, unless you first write “wrappers” using Fortran 2018 capabilities on the C side and offer up modern Fortran interfaces to them for the Fortran users including yourself.

Thanks to all for the replies. The problem is now clearer. SISL library will not handle any pointer automatically. I’ve underestimated the difficulties involved, however it was a good occasion for reviewing some Fortran-C interop concept.
Thanks

The declaration real(c_double):: ecoef(*) declares ecoef to be an assumed-size array. This is appropriate for the declaration of a dummy argument, but not allowed for a type component.