Interoperability with C
25.1 Calling C from Fortran
#include <math.h>
double c_norm(const double *x, int n) {
double s = 0.0;
for (int i = 0; i < n; ++i) s += x[i] * x[i];
return sqrt(s);
}
void c_greet(const char *name) { printf("Hello, %s!\n", name); }module clib
use, intrinsic :: iso_c_binding
implicit none
interface
function c_norm(x, n) bind(c, name="c_norm") result(r)
import :: c_double, c_int
real(c_double), intent(in) :: x(*)
integer(c_int), value :: n ! pass by value
real(c_double) :: r
end function c_norm
subroutine c_greet(name) bind(c, name="c_greet")
import :: c_char
character(kind=c_char), intent(in) :: name(*)
end subroutine c_greet
end interface
end module clib
program call_c
use clib
use, intrinsic :: iso_c_binding
implicit none
real(c_double) :: v(3) = [3.0_c_double, 4.0_c_double, 12.0_c_double]
print *, c_norm(v, 3_c_int) ! 13.0
call c_greet("Fortran" // c_null_char) ! C strings need a NUL terminator
end program call_cgcc -c clib.c && gfortran clib.o call_c.f90 -o call_c25.2 Calling Fortran from C
module flib
use, intrinsic :: iso_c_binding
implicit none
contains
subroutine scale_array(x, n, k) bind(c, name="scale_array")
integer(c_int), value :: n
real(c_double), intent(inout) :: x(n)
real(c_double), value :: k
x = x * k
end subroutine scale_array
end module flibvoid scale_array(double *x, int n, double k);
int main(void) { double a[3] = {1, 2, 3}; scale_array(a, 3, 2.0); return 0; }25.3 iso_c_binding essentials
integer(c_long), c_long_long, c_size_t, c_int64_t long, long long, size_t, int64_t real(c_float), real(c_double) float, double double _Complex type(c_ptr), type(c_funptr) void*, function pointer type, bind(c) c_loc(x), c_funloc(f) c_f_pointer(cptr, fptr, shape) convert C pointer to Fortran pointer c_null_ptr, c_null_char NULL, '\0'
25.4 Arrays, strings & memory ownership
Fortran arrays are column-major; C arrays row-major: A(i,j) in Fortran ↔ A[j][i] in C.
Use ISO_Fortran_binding.h (F2018 C descriptors, CFI_cdesc_t) to pass assumed-shape/allocatable arrays to C.
Decide who allocates and frees; don't free Fortran-allocated memory from C or vice versa.
C++: expose functions with extern "C".