Question

I'm having to write a subroutine that can be called both by C and by Fortran. This subroutine takes a file name as one of its arguments. I know that to interoperate nicely with C, the ISO C binding recommends using character arrays for interoperation.

The question I have is: is there such a thing as a character array literal that's easy to write? I have a subroutine like this:

subroutine my_sub(char_array)
  use iso_c_binding, only: c_char
  char(kind=c_char, len=1), dimension(:), intent(in) :: char_array
  ...
end subroutine my_sub

Is it possible to invoke this with something like:

call my_sub('Hello World!')

Or do I have to do something horrible like:

call my_sub((/ 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!' /))

My main issue seems to be that it doesn't like the assumed-shape array and that giving it a set (large) size also outputs all the garbage memory that happens to get picked up afterwards.

Is there a better way of doing this?

Was it helpful?

Solution

The rules of sequence association allow similar situation. You can use

call my_sub('Hello World!')

but only if you make your array assumed size dimension(*) or explicit shape.

Generally, in Fortran 2008 you cannot use assumed shape arrays for C-interoperable procedures. This will change i the future, but will be more complicated.

One other important remark. Just using iso_c_binding module doesn't make the procedure C-interoperable. You have to use bind(C), possibly with binding name. That's the important thing. You can create interoperable procedures even without the module (only limited ones). The feature of passing the string instead of 1-character array also depends on this.

This is why i don't like saying "use iso_c_binding to create interoperable procedures".

The interface to the procedure will have to explicit in Fortran.

OTHER TIPS

You can use transfer function. Here is an example code.

program string0
  implicit none
  character, allocatable :: string(:)
  character(len = :), allocatable :: text

  text = 'this is a pen'
  string = transfer(text, ' ', size = len_trim(text))
  string = achar(iachar(string) - 32)
  text = transfer(string, text)
  print *, text

  stop
end program string0
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top