1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- Copyright (C) 1999-2023 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with the
Invariant Sections being "Funding Free Software", the Front-Cover
Texts being (a) (see below), and with the Back-Cover Texts being (b)
(see below). A copy of the license is included in the section entitled
"GNU Free Documentation License".
(a) The FSF's Front-Cover Text is:
A GNU Manual
(b) The FSF's Back-Cover Text is:
You have freedom to copy and modify this GNU Manual, like GNU
software. Copies published by the Free Software Foundation raise
funds for GNU development. -->
<!-- Created by GNU Texinfo 5.1, http://www.gnu.org/software/texinfo/ -->
<head>
<title>The GNU Fortran Compiler: Interoperable Subroutines and Functions</title>
<meta name="description" content="The GNU Fortran Compiler: Interoperable Subroutines and Functions">
<meta name="keywords" content="The GNU Fortran Compiler: Interoperable Subroutines and Functions">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="index.html#Top" rel="start" title="Top">
<link href="Option-Index.html#Option-Index" rel="index" title="Option Index">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Interoperability-with-C.html#Interoperability-with-C" rel="up" title="Interoperability with C">
<link href="Working-with-C-Pointers.html#Working-with-C-Pointers" rel="next" title="Working with C Pointers">
<link href="Interoperable-Global-Variables.html#Interoperable-Global-Variables" rel="previous" title="Interoperable Global Variables">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.indentedblock {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smallindentedblock {margin-left: 3.2em; font-size: smaller}
div.smalllisp {margin-left: 3.2em}
kbd {font-style:oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nocodebreak {white-space:nowrap}
span.nolinebreak {white-space:nowrap}
span.roman {font-family:serif; font-weight:normal}
span.sansserif {font-family:sans-serif; font-weight:normal}
ul.no-bullet {list-style: none}
-->
</style>
</head>
<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
<a name="Interoperable-Subroutines-and-Functions"></a>
<div class="header">
<p>
Next: <a href="Working-with-C-Pointers.html#Working-with-C-Pointers" accesskey="n" rel="next">Working with C Pointers</a>, Previous: <a href="Interoperable-Global-Variables.html#Interoperable-Global-Variables" accesskey="p" rel="previous">Interoperable Global Variables</a>, Up: <a href="Interoperability-with-C.html#Interoperability-with-C" accesskey="u" rel="up">Interoperability with C</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<a name="Interoperable-Subroutines-and-Functions-1"></a>
<h4 class="subsection">6.1.4 Interoperable Subroutines and Functions</h4>
<a name="index-C-procedure-interoperability"></a>
<a name="index-procedure-interoperability-with-C"></a>
<a name="index-function-interoperability-with-C"></a>
<a name="index-subroutine-interoperability-with-C"></a>
<a name="index-interoperability_002c-subroutine-and-function"></a>
<p>Subroutines and functions have to have the <code>BIND(C)</code> 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.
</p>
<p>To pass a variable by value, use the <code>VALUE</code> attribute.
Thus, the following C prototype
</p>
<div class="smallexample">
<pre class="smallexample"><code>int func(int i, int *j)</code>
</pre></div>
<p>matches the Fortran declaration
</p>
<div class="smallexample">
<pre class="smallexample"> integer(c_int) function func(i,j)
use iso_c_binding, only: c_int
integer(c_int), VALUE :: i
integer(c_int) :: j
</pre></div>
<p>Note that pointer arguments also frequently need the <code>VALUE</code> attribute,
see <a href="Working-with-C-Pointers.html#Working-with-C-Pointers">Working with C Pointers</a>.
</p>
<p>Strings are handled quite differently in C and Fortran. In C a string
is a <code>NUL</code>-terminated array of characters while in Fortran each string
has a length associated with it and is thus not terminated (by e.g.
<code>NUL</code>). For example, if you want to use the following C function,
</p>
<div class="smallexample">
<pre class="smallexample"> #include <stdio.h>
void print_C(char *string) /* equivalent: char string[] */
{
printf("%s\n", string);
}
</pre></div>
<p>to print “Hello World” from Fortran, you can call it using
</p>
<div class="smallexample">
<pre class="smallexample"> 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)
</pre></div>
<p>As the example shows, you need to ensure that the
string is <code>NUL</code> terminated. Additionally, the dummy argument
<var>string</var> of <code>print_C</code> is a length-one assumed-size
array; using <code>character(len=*)</code> is not allowed. The example
above uses <code>c_char_"Hello World"</code> to ensure the string
literal has the right type; typically the default character
kind and <code>c_char</code> are the same and thus <code>"Hello World"</code>
is equivalent. However, the standard does not guarantee this.
</p>
<p>The use of strings is now further illustrated using the C library
function <code>strncpy</code>, whose prototype is
</p>
<div class="smallexample">
<pre class="smallexample"> char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
</pre></div>
<p>The function <code>strncpy</code> copies at most <var>n</var> characters from
string <var>s2</var> to <var>s1</var> and returns <var>s1</var>. In the following
example, we ignore the return value:
</p>
<div class="smallexample">
<pre class="smallexample"> 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
</pre></div>
<p>The intrinsic procedures are described in <a href="Intrinsic-Procedures.html#Intrinsic-Procedures">Intrinsic Procedures</a>.
</p>
<hr>
<div class="header">
<p>
Next: <a href="Working-with-C-Pointers.html#Working-with-C-Pointers" accesskey="n" rel="next">Working with C Pointers</a>, Previous: <a href="Interoperable-Global-Variables.html#Interoperable-Global-Variables" accesskey="p" rel="previous">Interoperable Global Variables</a>, Up: <a href="Interoperability-with-C.html#Interoperability-with-C" accesskey="u" rel="up">Interoperability with C</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
</div>
</body>
</html>
|