<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
<html>
|
<!-- Copyright (C) 1999-2016 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.2, http://www.gnu.org/software/texinfo/ -->
|
<head>
|
<title>The GNU Fortran Compiler: Working with Pointers</title>
|
|
<meta name="description" content="The GNU Fortran Compiler: Working with Pointers">
|
<meta name="keywords" content="The GNU Fortran Compiler: Working with Pointers">
|
<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="Further-Interoperability-of-Fortran-with-C.html#Further-Interoperability-of-Fortran-with-C" rel="next" title="Further Interoperability of Fortran with C">
|
<link href="Interoperable-Subroutines-and-Functions.html#Interoperable-Subroutines-and-Functions" rel="prev" title="Interoperable Subroutines and Functions">
|
<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="Working-with-Pointers"></a>
|
<div class="header">
|
<p>
|
Next: <a href="Further-Interoperability-of-Fortran-with-C.html#Further-Interoperability-of-Fortran-with-C" accesskey="n" rel="next">Further Interoperability of Fortran with C</a>, Previous: <a href="Interoperable-Subroutines-and-Functions.html#Interoperable-Subroutines-and-Functions" accesskey="p" rel="prev">Interoperable Subroutines and Functions</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="Working-with-Pointers-1"></a>
|
<h4 class="subsection">7.1.5 Working with Pointers</h4>
|
|
<p>C pointers are represented in Fortran via the special opaque derived type
|
<code>type(c_ptr)</code> (with private components). Thus one needs to
|
use intrinsic conversion procedures to convert from or to C pointers.
|
</p>
|
<p>For some applications, using an assumed type (<code>TYPE(*)</code>) can be an
|
alternative to a C pointer; see
|
<a href="Further-Interoperability-of-Fortran-with-C.html#Further-Interoperability-of-Fortran-with-C">Further Interoperability of Fortran with C</a>.
|
</p>
|
<p>For example,
|
</p>
|
<div class="smallexample">
|
<pre class="smallexample"> use iso_c_binding
|
type(c_ptr) :: cptr1, cptr2
|
integer, target :: array(7), scalar
|
integer, pointer :: pa(:), ps
|
cptr1 = c_loc(array(1)) ! The programmer needs to ensure that the
|
! array is contiguous if required by the C
|
! procedure
|
cptr2 = c_loc(scalar)
|
call c_f_pointer(cptr2, ps)
|
call c_f_pointer(cptr2, pa, shape=[7])
|
</pre></div>
|
|
<p>When converting C to Fortran arrays, the one-dimensional <code>SHAPE</code> argument
|
has to be passed.
|
</p>
|
<p>If a pointer is a dummy-argument of an interoperable procedure, it usually
|
has to be declared using the <code>VALUE</code> attribute. <code>void*</code>
|
matches <code>TYPE(C_PTR), VALUE</code>, while <code>TYPE(C_PTR)</code> alone
|
matches <code>void**</code>.
|
</p>
|
<p>Procedure pointers are handled analogously to pointers; the C type is
|
<code>TYPE(C_FUNPTR)</code> and the intrinsic conversion procedures are
|
<code>C_F_PROCPOINTER</code> and <code>C_FUNLOC</code>.
|
</p>
|
<p>Let us consider two examples of actually passing a procedure pointer from
|
C to Fortran and vice versa. Note that these examples are also very
|
similar to passing ordinary pointers between both languages. First,
|
consider this code in C:
|
</p>
|
<div class="smallexample">
|
<pre class="smallexample">/* Procedure implemented in Fortran. */
|
void get_values (void (*)(double));
|
|
/* Call-back routine we want called from Fortran. */
|
void
|
print_it (double x)
|
{
|
printf ("Number is %f.\n", x);
|
}
|
|
/* Call Fortran routine and pass call-back to it. */
|
void
|
foobar ()
|
{
|
get_values (&print_it);
|
}
|
</pre></div>
|
|
<p>A matching implementation for <code>get_values</code> in Fortran, that correctly
|
receives the procedure pointer from C and is able to call it, is given
|
in the following <code>MODULE</code>:
|
</p>
|
<div class="smallexample">
|
<pre class="smallexample">MODULE m
|
IMPLICIT NONE
|
|
! Define interface of call-back routine.
|
ABSTRACT INTERFACE
|
SUBROUTINE callback (x)
|
USE, INTRINSIC :: ISO_C_BINDING
|
REAL(KIND=C_DOUBLE), INTENT(IN), VALUE :: x
|
END SUBROUTINE callback
|
END INTERFACE
|
|
CONTAINS
|
|
! Define C-bound procedure.
|
SUBROUTINE get_values (cproc) BIND(C)
|
USE, INTRINSIC :: ISO_C_BINDING
|
TYPE(C_FUNPTR), INTENT(IN), VALUE :: cproc
|
|
PROCEDURE(callback), POINTER :: proc
|
|
! Convert C to Fortran procedure pointer.
|
CALL C_F_PROCPOINTER (cproc, proc)
|
|
! Call it.
|
CALL proc (1.0_C_DOUBLE)
|
CALL proc (-42.0_C_DOUBLE)
|
CALL proc (18.12_C_DOUBLE)
|
END SUBROUTINE get_values
|
|
END MODULE m
|
</pre></div>
|
|
<p>Next, we want to call a C routine that expects a procedure pointer argument
|
and pass it a Fortran procedure (which clearly must be interoperable!).
|
Again, the C function may be:
|
</p>
|
<div class="smallexample">
|
<pre class="smallexample">int
|
call_it (int (*func)(int), int arg)
|
{
|
return func (arg);
|
}
|
</pre></div>
|
|
<p>It can be used as in the following Fortran code:
|
</p>
|
<div class="smallexample">
|
<pre class="smallexample">MODULE m
|
USE, INTRINSIC :: ISO_C_BINDING
|
IMPLICIT NONE
|
|
! Define interface of C function.
|
INTERFACE
|
INTEGER(KIND=C_INT) FUNCTION call_it (func, arg) BIND(C)
|
USE, INTRINSIC :: ISO_C_BINDING
|
TYPE(C_FUNPTR), INTENT(IN), VALUE :: func
|
INTEGER(KIND=C_INT), INTENT(IN), VALUE :: arg
|
END FUNCTION call_it
|
END INTERFACE
|
|
CONTAINS
|
|
! Define procedure passed to C function.
|
! It must be interoperable!
|
INTEGER(KIND=C_INT) FUNCTION double_it (arg) BIND(C)
|
INTEGER(KIND=C_INT), INTENT(IN), VALUE :: arg
|
double_it = arg + arg
|
END FUNCTION double_it
|
|
! Call C function.
|
SUBROUTINE foobar ()
|
TYPE(C_FUNPTR) :: cproc
|
INTEGER(KIND=C_INT) :: i
|
|
! Get C procedure pointer.
|
cproc = C_FUNLOC (double_it)
|
|
! Use it.
|
DO i = 1_C_INT, 10_C_INT
|
PRINT *, call_it (cproc, i)
|
END DO
|
END SUBROUTINE foobar
|
|
END MODULE m
|
</pre></div>
|
|
<hr>
|
<div class="header">
|
<p>
|
Next: <a href="Further-Interoperability-of-Fortran-with-C.html#Further-Interoperability-of-Fortran-with-C" accesskey="n" rel="next">Further Interoperability of Fortran with C</a>, Previous: <a href="Interoperable-Subroutines-and-Functions.html#Interoperable-Subroutines-and-Functions" accesskey="p" rel="prev">Interoperable Subroutines and Functions</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>
|