| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| <html> |
| <!-- Copyright (C) 1999-2014 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> |