# Experiment: dealing with a pointer to a string from C

**URL:** <https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930>\
**Category:** Uncategorized\
**Created:** [March 30, 2021, 1:53pm UTC](https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930 "2021-03-30T13:53:45Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [March 30, 2021, 1:53pm UTC](https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930/1 "2021-03-30T13:53:45Z")

</div>

I was experimenting with an interface to a C library and realised that I would need to deal with pointers to C strings and if possible in a way that is transparent on the Fortran side. So: turn the type(c\_ptr) into a string that behaves as if it is an ordinary Fortran string (because otherwise dealing with them is awkward). There are a number of possibilities for that, one being creating a copy of the contents in an ordinary Fortran variable. But what if I want to avoid the copy?

Well, here is the C code as an example, the function returns a pointer to a string ending in a NUL character:

```
/* getstring.c --
   Trivial function to return a static string   
*/

#include <string.h>

void getstring_c( char **string, int *length ) {

     *string = "Hello" ;
     *length = strlen(*string) ;
}

```

(quite trivial, but the interface is typical for what I was dealing with)

The Fortran program below calls this function and turns the pointer into a Fortran pointer that behaves as a string of the right length:

```
program string_pointer
    implicit none

    character(len=:), pointer :: p_string

    call getstring( p_string)
    write(*,*) '>', p_string, '<'
    write(*,*) len(p_string)

contains
subroutine getstring( p_string )
    use iso_c_binding
    character(len=:), pointer :: p_string

    interface
        subroutine getstring_c( c_string, length ) bind(C)
            import :: c_ptr
            type(c_ptr), intent(out) :: c_string
            integer, intent(out) :: length
        end subroutine getstring_c
    end interface

    type(c_ptr) :: c_string
    integer :: length

    call getstring_c( c_string, length )

    call c_f_pointer( c_string, p_string )

    p_string => p_string(1:length) ! Would that work? Yes :)
end subroutine getstring

end program string_pointer

```

I was pleased to see it works. No copy required, no array of individual characters, simply a string. I only hope it is standard-conforming. What are other possibilities to achieve this?

The goal I have in mind: provide an interface to such a C library with a minimal amount of C code.

---

<div class="post-metadata">

**Author:** ![rwmsu](https://avatars.discourse-cdn.com/v4/letter/r/48db29/32.png) [@rwmsu](https://fortran-lang.discourse.group/u/rwmsu)\
**Post date:** [March 30, 2021, 3:13pm UTC](https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930/2 "2021-03-30T15:13:59Z")

</div>

Arjen

The “pattern” you use (return C string as C\_PTR and use c\_f\_pointer to map it to  
something you can use in Fortran) is the only one I know that works but thats not  
to say there aren’t others. One issue you need to think about though is how and when  
do you free the memory allocated in the C function for the string it returns. If you  
want to make your function so that it hides the C side as much as possible from  
Fortran programmers it might be better to just make a copy of the string (something  
you appear to want to avoid) and free the C\_PTR returned by the C function inside getstring.  
That way you have some protection against memory leaks. This means you will have to make  
a C-interop interface for the C free function but thats trivial. You also want to add some logic  
to strip C NULL chars.

Also, I didn’t know that you could use a deferred length character pointer that way. Thanks for  
showing that, its a good trick to know.

RW

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [March 30, 2021, 6:49pm UTC](https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930/3 "2021-03-30T18:49:29Z")

</div>

See this [**thread**](https://fortran-lang.discourse.group/t/iso-c-binding-interface-to-a-c-function-returning-a-string/527/13).

Another option - one I recommend - is better, higher-level code in C; it can be wrappers to existing functions.

```C
#include <string.h>
#include "ISO_Fortran_binding.h"

static char *str = "Hello";

void getstring_c( char **string, size_t *length ) {

     *string = str;
     *length = strlen(*string) ;
}

// Wrapper for Fortran users
int getstr( CFI_cdesc_t *s ) {

    int irc = CFI_establish(s, str, CFI_attribute_pointer, CFI_type_char,
                            strlen(str), (CFI_rank_t)0, NULL);
    return irc;
}

```

Then the modern Fortran code is simply:

```Fortran
   use, intrinsic :: iso_c_binding, only : c_int, c_char

   interface
      function getstr( str ) result(irc) bind(C, name="getstr")
         import :: c_int, c_char
         implicit none
         ! Argument list
         character(kind=c_char, len=:), pointer, intent(out) :: str
         ! Function result
         integer(c_int) :: irc
      end function 
   end interface

   character(kind=c_char, len=:), pointer :: s
   integer(c_int) :: irc

   irc = getstr( s )
   if ( irc == 0 ) then 
      print *, "s: ", s, "; expected is Hello"
      print *, "len: ", len(s), "; expected is 5"
   else
      print *, "getstr function returned an error."
   end if
   
end 

```

> C:\Temp\>cl /c /W3 /EHsc c.c  
> Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29337 for x64  
> Copyright (C) Microsoft Corporation. All rights reserved.
> 
> c.c
> 
> C:\Temp\>ifort /c /standard-semantics /warn:all /stand:f18 f.f90  
> Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1.2 Build 20201208\_000000  
> Copyright (C) 1985-2020 Intel Corporation. All rights reserved.
> 
> C:\Temp\>link f.obj c.obj /subsystem:console /out:f.exe  
> Microsoft (R) Incremental Linker Version 14.28.29337.0  
> Copyright (C) Microsoft Corporation. All rights reserved.
> 
> C:\Temp\>f.exe  
> s: Hello; expected is Hello  
> len: 5 ; expected is 5
> 
> C:\Temp\>

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [March 31, 2021, 6:57am UTC](https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930/4 "2021-03-31T06:57:14Z")

</div>

Yes, the issue of freeing the memory is certainly a vexing one. In the case of this library, it is probably better to always return a copy of the sring, so that the memory management is not done in two separate places. The C library knows when to free the C string and on the Fortran side of the interface, it is up to the Fortran program to do the right thing. Mixing up the memory management is asking for trouble.  
However, I know that the string is managed nicely by the C library and therefore I could safely leave it to that library. Well, an experiment like I said 🙂

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [March 31, 2021, 7:00am UTC](https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930/5 "2021-03-31T07:00:28Z")

</div>

Oh, that is nice! I have not used the ISO\_Fortran\_binding.h stuff yet. I should have a closer look.

---

<div class="post-metadata">

**Author:** ![billlong](https://avatars.discourse-cdn.com/v4/letter/b/71e660/32.png) [@billlong](https://fortran-lang.discourse.group/u/billlong)\
**Post date:** [March 31, 2021, 12:40pm UTC](https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930/6 "2021-03-31T12:40:48Z")

</div>

The draft for F202X has two functions in the iso\_c\_binding module to handle converting between Fortran and C strings: C\_F\_STRPOINTER and F\_C\_STRING.

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [March 31, 2021, 12:43pm UTC](https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930/7 "2021-03-31T12:43:02Z")

</div>

Great, that should make it all a lot easier

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [April 1, 2021, 2:23pm UTC](https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930/8 "2021-04-01T14:23:59Z")

</div>

Another option in the interim is a `BLOCK` construct:

```auto
program string_pointer
   use iso_c_binding
   implicit none
   interface
      subroutine getstring_c( c_string, length ) bind(C)
         import :: c_ptr
         implicit none
         type(c_ptr), intent(out) :: c_string
         integer, intent(out) :: length
      end subroutine getstring_c
   end interface
   character(kind=c_char, len=:), pointer :: p_string
   type(c_ptr) :: c_string
   integer :: length

   call getstring_c( c_string, length )
   block
      character(kind=c_char, len=length), pointer :: t_string
      call c_f_pointer( c_string, t_string )
      p_string => t_string
      t_string => null()
   end block
   write(*,*) '>', p_string, '<'
   write(*,*) len(p_string)

end program string_pointer

```

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [April 1, 2021, 2:41pm UTC](https://fortran-lang.discourse.group/t/experiment-dealing-with-a-pointer-to-a-string-from-c/930/9 "2021-04-01T14:41:45Z")

</div>

The advantage of that solution is that you avoid a companion C compiler. Ingenious!
