2
subroutine func01( a ) bind(C,name="func01")
  implicit none
  character(len=30), dimension(3) , intent(in) :: a

    print *
    print *, "char length = ", len(a(1)), len(a(2)), len(a(3))
    print *, "raw a(1) : [", a(1), "]"
    print *, "raw a(2) : [", a(2), "]"
    print *, "raw a(3) : [", a(3), "]"
    print *, "trim     : [", trim(a(1)), "] [", trim(a(2)), "]  [", trim(a(3)), "]"
end

When I try to compile the above code I get the following messages:

gfortran source3.f90

source3.f90:1.20:

subroutine func01( a ) bind(C,name="func01")
                    1
Warning: Variable 'a' at (1) is a parameter to the BIND(C) procedure 'func01' bu
t may not be C interoperable
source3.f90:1.20:

subroutine func01( a ) bind(C,name="func01")
                    1
Error: Character argument 'a' at (1) must be length 1 because procedure 'func01'
 is BIND(C)

Can you please tell me on how to get rid of the messages?

bjdesa
  • 63
  • 2
  • 9
  • 1
    As you can see in http://stackoverflow.com/tags/fortran-iso-c-binding/info `a` isn't an interoperable thing (it isn't of length 1).. You will be able to find many other questions about passing a string from C to Fortran. – francescalus Sep 30 '15 at 17:10
  • It compiles just fine with ifort intel compiler – bjdesa Sep 30 '15 at 17:13
  • 2
    Yeah, Intel allows that, but that is their non-standard choice. – Vladimir F Героям слава Sep 30 '15 at 17:19
  • How do I fix it to run with gfortran – bjdesa Sep 30 '15 at 17:24
  • You will have to restructure it to use character(1) arrays. We cannot say more, because we cannot see the rest of the code, but it will have to be restructured, not just one line changed. – Vladimir F Героям слава Sep 30 '15 at 19:29
  • See for example http://stackoverflow.com/q/8207997/577108, and maybe http://stackoverflow.com/q/9972743/577108 – haraldkl Sep 30 '15 at 19:42
  • can you add at least the declared C interface `func01` to this post and how you are calling that function in C? – casey Sep 30 '15 at 20:17
  • extern "C" { void func01( char *c, const int len ); } – bjdesa Sep 30 '15 at 21:43
  • http://stackoverflow.com/questions/30419704/fortran-pass-character81-array-to-c-c-code – bjdesa Sep 30 '15 at 21:48
  • subroutine func01( a ) bind(C,name="func01") implicit none character(len=1), dimension(90) , intent(in) :: a character(len=30), dimension(3) :: b integer*4 :: count,i,j count=1 do j=1,3 b(J)='' do I=1,30 b(J)=trim(b(J))//a(count) count=count+1 enddo enddo print * print *, "char length = ", len(b(1)), len(b(2)), len(b(3)) print *, "raw a(1) : [", b(1), "]" print *, "raw a(2) : [", b(2), "]" print *, "raw a(3) : [", b(3), "]" print *, "trim : [", trim(b(1)), "] [", trim(b(2)), "] [", trim(b(3)), "]" end – bjdesa Oct 01 '15 at 22:18
  • @bjdesa What? If you have some new code edit it into the question and format it properly. This is absolutely unreadable. – Vladimir F Героям слава Oct 08 '15 at 08:59

1 Answers1

4

A character argument of a Fortran bind(C) interoperable procedure must have length 1.

But one can use the same approach as in C, use the arrays of characters.

If you have

char ch[5]

use

character(kind=c_char) :: ch(5)

If you have

char* ch;
int n;

ch = malloc(n);
fortran_sub(ch, n);

use

subroutine fortran_sub(ch, n) bind(C, name="fortran_sub")
  integer(c_int), value :: n
  character(kind = c_char) :: ch(n)

Note that the character array will be null delimited.

If you are calling C and passing the character array there, it is your responsibility to delimit it by c_char_null.

  • Maybe I'm missing something here, but how do you do then a clean interoperation between C and Fortran. It seems you need to first convert all your arrays `ch(n)` to `character(len=n) :: new_ch` before you can work it properly in Fortran. – kvantour Mar 26 '19 at 08:58
  • @kvantour See notes 18.17 and 18.21 in Fortran 2015 draft (in final F2018 the numbers may differ). *"Fortran’s rules of sequence association (15.5.2.11) permit a character scalar actual argument to correspond to a dummy argument array. This makes it possible to argument associate a Fortran character string with a C string. Note 18.21 has an example of interoperation between Fortran and C strings."* – Vladimir F Героям слава Mar 26 '19 at 09:19