Next: Working with Pointers, Previous: Interoperable Global Variables, Up: Interoperability with C [Contents][Index]
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]