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.
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.
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.