First, I assume that you define dp as a parameter in a module somewhere. You can just use
integer, parameter :: dp = c_double
in this module (and where if (dp /= c_double) stop "Bletchful sytem" .
Array transfer between C and Fortran works as follows:
module foo use iso_c_binding private public :: bar interface subroutine bar(a,n) bind(C) import real(kind=c_double), dimension(*), intent(inout) :: a integer(c_size_t), value, intent(in) :: n end subroutine bar end interface end module foo
Your function c will
void bar(double *a, size_t n)
Edit:
A way to call your C function from Fortran would be
program main use iso_c_binding use foo real(c_double), dimension(10) :: a call bar(a,size(a,kind=c_size_t)) print *,a end program main
Edit 2:
If you really want to copy / copy every time, you can do something like
subroutine bar2(array) real(kind=c_double), intent(inout), dimension(:) :: array real(kind=c_double), dimension(size(array)) :: a a = array ! Copy in call bar(a,size(a,kind=c_size_t)) array = a ! Copy out end subroutine bar2 end module foo
But I do not understand why this is necessary.
Edit 3:
If you are afraid of a mismatch between the C and Fortran data types, you can write a generic wrapper to get around this. Here's what it looks like:
module foo use iso_c_binding implicit none private public :: bar interface subroutine bar_double(a,n) bind(C) import real(kind=c_double), dimension(*), intent(inout) :: a integer(c_size_t), value, intent(in) :: n end subroutine bar_double end interface interface subroutine bar_float(a,n) bind(C) import real(kind=c_float), dimension(*), intent(inout) :: a integer(c_size_t), value, intent(in) :: n end subroutine bar_float end interface interface bar module procedure bar_aux_double, bar_aux_float end interface bar contains subroutine bar_aux_double (a) real(kind=c_double), dimension(:), intent(inout) :: a call bar_double (a, size(a,kind=c_size_t)) end subroutine bar_aux_double subroutine bar_aux_float (a) real(kind=c_float), dimension(:), intent(inout) :: a call bar_float (a, size(a,kind=c_size_t)) end subroutine bar_aux_float end module foo
Your main program would then look like
program main use foo integer, parameter :: dp = selected_real_kind(15) integer, parameter :: sp = selected_real_kind(6) real(dp), dimension(10) :: a_dp real(sp), dimension(10) :: a_sp call bar(a_dp) call bar(a_sp) print *,a_dp,a_sp end program main
where you donโt refer to iso_c_binding at all. If there is no wrapper function for dp or sp, compilation will fail due to the lack of a general procedure.