Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Fortran 90 - Derived data types with a derived data type member

Status
Not open for further replies.

sjster

Technical User
Feb 26, 2011
2
US
Hi,

I am trying to send a derived data type , which has a derived data type as a member, to a 'C' function. However from the C function trying to access to access the derived type member results in a segmentation fault. For more context here is the little snippet of code..

TYPE :: TEST
SEQUENCE
INTEGER :: x, y, z
END TYPE TEST

TYPE :: point
SEQUENCE
INTEGER :: x, y, z
integer, dimension:)), allocatable :: node
type(TEST) , allocatable :: testvar:))
END TYPE point

Now I declare an object of type 'point' and allocate memory for the variables as..

TYPE (point) base
ALLOCATE(base%node(4))
ALLOCATE(base%testvar(5))

and pass 'base' to a C function. I can access the equivalent of 'base%x' and 'base%node' from C , however trying to access 'testvar' results in a segmentation fault. I am missing something here...Any help would be appreciated...


Thanks,
Sj
 
Are you passing a structure from C to fortran and allocating the innards of the structure in Fortran?

What happens if you do all the allocations in C and pass them into Fortran. Have a look in the debugger and see what values you can see.

Which compiler/OS are you using?
 
you cannot pass to C a derived type containing POINTER of ALLOCATABLE elements. The reason is simple : C pointers are just addresses whereas FORTRAN allocatable or pointer variables are much more complicated (they also contain the dimensions)

In addition you should use BIND(C) instead of SEQUENCE. If you want to be compatible with C, all variables must use C compatible types. For that you have to use the iso_c_binding intrinsic module (FORTRAN2003). The derived type C_PTR is especially useful to pass arrays with are allocated dynamically.

Example :

Code:
program t

  use iso_c_binding
  
  implicit none
  
  type, bind(c) :: test
    integer(c_int) :: x, y, z
  end type test
  
  type, bind(c) :: point
    integer(c_int) :: x, y, z
    integer(c_int) :: nnode,nvar
    type(c_ptr) :: node
    type(c_ptr) :: testvar
  end type point
  
  type(point) :: base
  integer(c_int),allocatable :: node(:)
  type(test),allocatable :: testvar(:)
  
  allocate(node(4),testvar(5))
  
  base%nnode=size(node)
  base%nvar=size(testvar)
  base%node=C_LOC(node)
  base%testvar=C_LOC(testvar)
  
  CALL c_routine(base)
  
end program

The corresponding C structures are easy to imagine...

François Jacq
 
Re bind(c) - that is why I asked which compiler was being used. That didn't exist on earlier compilers.
 
Thank you both for your replies !

@xwb - I am allocating data in fortran and sending it to a C function. And it is a GNU Toolchain project on Linux. I am porting sections to accelerate on a GPU using CUDA...

@Jacq - Thanks a ton for clarifying that , and so far that seems to do the trick. My derived data structures get immensely more complicated now...but atleast I know what direction I am headed in. If it is not too much , can you recommend a good source of reference on this topic...( Fortran and C mixed language programming )

Thanks,
Sj
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top