Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29352 Discussions

Passing char** between C and Fortran?

ivfuser
Beginner
1,337 Views
Hi. Can someone loan me a clue? I am successfully passing strings between Fortran CHARACTER(*) and C char* types. But I'm having a little difficulty generalizing this to arrays of strings. Namely, I would like to map Fortran CHARACTER*(*) to C char**.

(Please excuse the obsolete-in-F95 form, which I use above for conciseness.)

My preferred interface uses the C calling convention and decoration, but with strings passed by reference (only). So I am trying to generalize

interface
subroutine mySub( string )
!DEC$ ATTRIBUTES C, DECORATE, ALIAS:'extSub' :: mySub
character(*) :: string
!DEC$ATTRIBUTES REFERENCE :: string
end subroutine
end interface

which is caught by

void extSun( char *str )


for a single string to something more like

interface
subroutine mySub( string )
!DEC$ ATTRIBUTES C, DECORATE, ALIAS:'extSub' :: mySub
character(*) :: string(*)
!DEC$ATTRIBUTES REFERENCE :: string
end subroutine
end interface

caught by some C like

void extSun( char *str[] )

for an array of strings.

IVF will happily compile and link with a C object this way, but str[1] on the C side ends up with an invalid (out-of-process) pointer at runtime. Am I barking up the wrong tree here?

Thanks!
0 Kudos
4 Replies
TimP
Honored Contributor III
1,337 Views
CHARACTER*(*) is just a string of characters, with a separate system-dependent way of passing the length. It's no different from CHARACTER(len=*).
0 Kudos
ivfuser
Beginner
1,337 Views
Tim,

Ok. My bad. I guess I picked this up by osmosis and assumed too much. I don't like system-dependence, so I will get out of this habit.

Thanks!
0 Kudos
Steven_L_Intel1
Employee
1,337 Views
The "system dependent" is nothing you can get away from - not yet at least. And it isn't really the issue here. C's char** is an array of pointers to strings, not an array of strings (in the Fortran sense.) You'd have to implement this as an array of INTEGER(INT_PTR_KIND()) and then use the Integer POINTER extension (not the Fortran 90 POINTER) to dereference each element.
0 Kudos
ivfuser
Beginner
1,337 Views
Steve,

Ah. A dim light goes on over my head. Now I understand well enough to know that I want to do something else.

Thanks!
0 Kudos
Reply