Passing a structured data type from Fortran to C++

2019-07-14 18:34发布

问题:

This question already has an answer here:

  • Fortran derived types containing pointers to be accessible from C 1 answer

I have a structured type in Fortran that contains lots of data including pointers (real*8 pointer data type).

I am developing a C++ API for some Fortran routine. I need the contents of the structure to persist between calls to the Fortran routine.

I was thinking about getting the address of the structure using loc and pass the address to the C++ side.

When Fortran routine is called again from C++ and the address is passed back to Fortran, somehow typecast it to the original structure and then use it for computation.

What approach can I use to accomplish this?

Thanks.

EDIT: my code based on the comments/suggestions. The program crashes when C_LOC is called (if I comment out the call to C_LOC then the program does not crash).

subroutine TEST(a,b,c,d,e,mystruct,ier) BIND(C, NAME='TEST')
use mymodule
USE, INTRINSIC :: ISO_C_BINDING

implicit none
TYPE(C_PTR)                 :: mystruct
TYPE(mymodule), TARGET      :: origstruct
INTEGER                     :: a, b, c
DOUBLE PRECISION            :: d(*), e(*)
INTEGER                     :: ier

!Do something with origstruct and other arguments

print *, 'here 1'
mystruct= C_LOC(origstruct)
print *, 'here 2'

end

回答1:

Under Fortran 2003 (supported by most compilers nowadays), you can use the standard ISO_C_BINDING module. If you are happy with the obtained C pointer being "opaque" (that is, you just want a void*), you can use the C_LOC function:

use, intrinsic :: ISO_C_BINDING
type(your_struct_t), target :: your_obj
type(C_PTR) :: p

p = C_LOC(your_obj)

You can then pass this pointer to some C procedure:

interface
    subroutine mycproc(x, n, userdata) bind(C)
        use, intrinsic :: iso_c_binding
        integer(c_int), intent(in), value :: n
        real(c_double), intent(in) :: x(n)
        type(c_ptr), intent(in), value :: userdata
    end subroutine
end interface

call mycproc(x, size(x), p)