diff options
author | alk3pInjection <webmaster@raspii.tech> | 2024-02-04 16:16:35 +0800 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2024-02-04 16:16:35 +0800 |
commit | abdaadbcae30fe0c9a66c7516798279fdfd97750 (patch) | |
tree | 00a54a6e25601e43876d03c1a4a12a749d4a914c /share/doc/gfortran/Working-with-C-Pointers.html |
https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
Change-Id: I7303388733328cd98ab9aa3c30236db67f2e9e9c
Diffstat (limited to 'share/doc/gfortran/Working-with-C-Pointers.html')
-rw-r--r-- | share/doc/gfortran/Working-with-C-Pointers.html | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/share/doc/gfortran/Working-with-C-Pointers.html b/share/doc/gfortran/Working-with-C-Pointers.html new file mode 100644 index 0000000..e1c70cb --- /dev/null +++ b/share/doc/gfortran/Working-with-C-Pointers.html @@ -0,0 +1,241 @@ +<!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: Working with C Pointers</title> + +<meta name="description" content="The GNU Fortran Compiler: Working with C Pointers"> +<meta name="keywords" content="The GNU Fortran Compiler: Working with C 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="previous" 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-C-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="previous">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-C-Pointers-1"></a> +<h4 class="subsection">6.1.5 Working with C Pointers</h4> +<a name="index-C-pointers"></a> +<a name="index-pointers_002c-C"></a> + +<p>C pointers are represented in Fortran via the special opaque derived +type <code>type(c_ptr)</code> (with private components). C pointers are distinct +from Fortran objects with the <code>POINTER</code> attribute. Thus one needs to +use intrinsic conversion procedures to convert from or to C pointers. +For some applications, using an assumed type (<code>TYPE(*)</code>) can be +an alternative to a C pointer, and you can also use library routines +to access Fortran pointers from C. 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>Here is an example of using C pointers in Fortran: +</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="previous">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> |