7.1.4 Interoperable Subroutines and Functions
Subroutines and functions have to have the BIND(C)
attribute to be compatible with C. The dummy argument declaration is relatively straightforward. However, one needs to be careful because C uses call-by-value by default while Fortran behaves usually similar to call-by-reference. Furthermore, strings and pointers are handled differently. Note that in Fortran 2003 and 2008 only explicit size and assumed-size arrays are supported but not assumed-shape or deferred-shape (i.e. allocatable or pointer) arrays. However, those are allowed since the Technical Specification 29113, see Further Interoperability of Fortran with C
To pass a variable by value, use the VALUE
attribute. Thus, the following C prototype
int func(int i, int *j)
matches the Fortran declaration
integer(c_int) function func(i,j) use iso_c_binding, only: c_int integer(c_int), VALUE :: i integer(c_int) :: j
Note that pointer arguments also frequently need the VALUE
attribute, see Working with Pointers.
Strings are handled quite differently in C and Fortran. In C a string is a NUL
-terminated array of characters while in Fortran each string has a length associated with it and is thus not terminated (by e.g. NUL
). For example, if one wants to use the following C function,
#include <stdio.h> void print_C(char *string) /* equivalent: char string[] */ { printf("%s\n", string); }
to print “Hello World” from Fortran, one can call it using
use iso_c_binding, only: C_CHAR, C_NULL_CHAR interface subroutine print_c(string) bind(C, name="print_C") use iso_c_binding, only: c_char character(kind=c_char) :: string(*) end subroutine print_c end interface call print_c(C_CHAR_"Hello World"//C_NULL_CHAR)
As the example shows, one needs to ensure that the string is NUL
terminated. Additionally, the dummy argument string of print_C
is a length-one assumed-size array; using character(len=*)
is not allowed. The example above uses c_char_"Hello World"
to ensure the string literal has the right type; typically the default character kind and c_char
are the same and thus "Hello World"
is equivalent. However, the standard does not guarantee this.
The use of strings is now further illustrated using the C library function strncpy
, whose prototype is
char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
The function strncpy
copies at most n characters from string s2 to s1 and returns s1. In the following example, we ignore the return value:
use iso_c_binding implicit none character(len=30) :: str,str2 interface ! Ignore the return value of strncpy -> subroutine ! "restrict" is always assumed if we do not pass a pointer subroutine strncpy(dest, src, n) bind(C) import character(kind=c_char), intent(out) :: dest(*) character(kind=c_char), intent(in) :: src(*) integer(c_size_t), value, intent(in) :: n end subroutine strncpy end interface str = repeat('X',30) ! Initialize whole string with 'X' call strncpy(str, c_char_"Hello World"//C_NULL_CHAR, & len(c_char_"Hello World",kind=c_size_t)) print '(a)', str ! prints: "Hello WorldXXXXXXXXXXXXXXXXXXX" end
The intrinsic procedures are described in Intrinsic Procedures.
Next: Working with Pointers, Previous: Interoperable Global Variables, Up: Interoperability with C [Contents][Index]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gfortran/Interoperable-Subroutines-and-Functions.html