I am wanting to pass a vector of doubles, in a C-struct, from C to FORTRAN, so that it is stored in a derived type.
So far, I am able to pass a vector of int’s, via pointer. However when I pass a vector of doubles, I do not recover correct data.
This suggests to me the memory is not aligned properly, or that the types, even though I am using real(c_double), is not correct.
Hopefully, I can use this approach, because it is quite simple. I read usage of C descriptors, but hopefully this is not necessary (because this approach seems quite more involved).
I’ve also read this thread and taken what it says into account.
I posted the fortran code, and then the c++ code, below.
Fortran code to grab a vector of reals contained in a C-struct
subroutine send_cstruct_to_fortran(cstruct)
use iso_c_binding, only : c_int, c_ptr, c_f_pointer, C_FLOAT, C_DOUBLE
implicit none
! Fortran doesn't know how the c struct is defined, So, we use bind(c) to
! define a user defined type to match the c struct.
!
type, bind(c) :: cstruct_interface
integer(c_int) :: n
type(c_ptr) :: array
type(c_ptr) :: myvec
type(c_ptr) :: D
end type
! The struct that has been passed from c to fortran
type(cstruct_interface), intent(inout) :: cstruct
! We want to access cstruct%array.
! Thus we define array_local as a pointer to an array.
! We then use c_f_pointer to cast the c pointer cstruct%array to a
! fortran compatible pointer array_local. We can then use array_local
!
integer(4), pointer, dimension(:) :: array_local
integer(4), pointer, dimension(:) :: myvec_local
!integer(4), pointer, dimension(:) :: myvec2_local
real(kind=C_DOUBLE), pointer, dimension(:) :: myvec2_local
!real(C_FLOAT), pointer, dimension(:) :: myvec2_local !no!
!real(8), pointer, dimension(:) :: myvec2_local
call c_f_pointer(cstruct%array, array_local, [cstruct%n])
call c_f_pointer(cstruct%myvec, myvec_local, [cstruct%n])
call c_f_pointer(cstruct%D, myvec2_local, [cstruct%n])
end subroutine
cpp-code* → C++ function declaration
extern "C"
{
void send_cstruct_to_fortran_(struct blah* s);
}
cpp-code → C++ function declaration
struct blah s;
s.n = n;
//myvec2 is just a vector of doubles; n=5...
// try using fancy copy stuff in order to troubleshoot.
// in any case, the vector of doubles is being copied correctly.
s.D = (double*) malloc(sizeof(double) * myvec2.size());
size_t nbytes = sizeof(double) * myvec2.size();
std::memcpy(s.D, myvec2.data(), nbytes);
send_cstruct_to_fortran_(&s);