This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Mixed language documentation


Ciao Angelo,

Angelo Graziosi wrote:
> In the GFORTRAN manual, for the current development snapshot, it is
> reported an example on how to handle something like
>
> char *strncpy(...)
>
> Really, the example ignores the 'function' and uses the 'subroutine'.
> It says: "Ignore the return value of strncpy -> subroutine..."

Well, it only does so because why should bother to handle a return value
if one does not need it.

> But the interesting case is that of a C function that returns 'char *'.
> How to handle this case? I.E. we have a C function
>
> char *foo(){...}
>
> that is interfaced with:
>
> interface
>   function foo() bind(C)
>     use, intrinsic :: iso_c_binding
>      implicit none
>      type (C_PTR) :: foo
>    end function foo
> end interface
Looks fine so far.

> I would suggest using this declaration
>
> character(C_CHAR), dimension(:), pointer :: name=> null()
>
> but then 'gfortan' cries because it wants SHAPE in
> c_f_pointer(foo(),name)! (It would need a sort of 'strlen', I think)

Where is the problem? Just call strlen! The following program works for me:

$ cat int_c.c

#include <stdlib.h>
#include <string.h>

char *foo(void)
{
  char str[] = "Example";
  char *res =
  res = malloc (sizeof(str));
  strcpy (res, str);
  return res;
}

$ cat int_f.f90

program main
  use, intrinsic :: iso_c_binding
  implicit none

  interface
    function foo () bind(C)
      import
      type (C_PTR) :: foo
    end function foo
  end interface
  interface strlen
!! Note: as both strlen and strlen2 have the same binding name,
!! you can only use one of them at a time.
!    function strlen (str) bind(C)
!      import
!      character(kind=c_char) :: str(*)
!      integer(c_size_t) :: strlen
!    end function strlen
    function strlen2 (str) bind(C,name="strlen")
      import
      type(c_ptr), value :: str
      integer(c_size_t)  :: strlen2
    end function strlen2
  end interface strlen

  type(c_ptr) :: cstr
  character, pointer :: str(:)
  cstr = foo ()
  call c_f_pointer (cstr,str, [strlen(cstr)])
  print *, str
end program main

$ gfortran int_c.c int_f.f90
$ ./a.out
 Example


Tobias


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]