I have a C struct and a corresponding Fortran derived type which is defined with bind(c), and have successfully been passing instances back and forth using the syntax (in C):
myFortranRoutine(&myInteroperableStruct);
...and in Fortran:
subroutine myFortranRoutine(c_myInteroperableStruct) bind(c, name='myFortranRoutine') type(c_ptr), value :: c_myInteroperableStruct type(interoperableStruct), pointer :: myInteroperableStruct call c_f_pointer(c_myInteroperableStruct, myInteroperableStruct) call doInterestingStuff(myInteroperableStruct) end subroutine myFortranRoutine
For a variety of reasons it would be convenient to change the C call from passing a pointer to passing-by-value in cases where I don't require the struct to be changed by the Fortran routine. In other words, in C I'd like to write:
myFortranRoutine(myInteroperableStruct);
...and on the Fortran side I'd put:
subroutine myFortranRoutine(myInteroperableStruct) bind(c, name='myFortranRoutine') type(interoperableStruct), value:: myInteroperableStruct call doInterestingStuff(myInteroperableStruct) ! Obviously, any changes to myInteroperableStruct won't ! be returned to the C application end subroutine myFortranRoutine
The trouble is that, when I do this, the application compiles without any errors but at runtime there is a 24-byte offset in the structs: that is to say, in the Fortran code, the first 24 bytes of the struct contain apparent garbage, and the rest of the struct contains exactly what it should but with a fixed offset of 24 bytes.
Is this because I've got the syntax wrong, or simply because I'm doing something which isn't supported?