I am writing a module in c for a fortran program and I need to pass some strings to the fortran program. I am unable to modify the fortran code, but can write my own fortran code to call the existing code. I have tried googling this and there are a lot of different approaches written at a level that I don't understand.
The c string is of variable length (although it's set before being passed). The fortran "string" is declared as character*(*), so I don't see the length that the character array needs to be padded to. Here's some code fragments to see what I need to do.
c function that I'm writing:
void c_func(int db_handle) {
char *geom_name;
int geom_handle = 0;
size_t geom_name_len = db_get_len(db_handle); !gets the length of the name
geom_name = (char *)malloc(sizeof(char*(geom_name_len+1)));
db_pull(db_handle, geom_name); !pulls geom_name from db as a null terminated string
call_fortan_function(geom_handle, geom_name); !The fortran function will set the integer
...}
fortran function that I can't modify does some stuff with the name and then sets a value to the handle:
logical function f_fn(handle, name)
integer handle
character*(*) name
I assume the best way to do this will be to create a separate c function that parses geom_name into some stuff that fortran will use and then a fortran function to create the fortran string and pass it to the function that I can't change, but I don't know how to do that. Any help?
You cannot portably call Fortran procedure requiring character(*)
from C. It is not possible, because the procedure takes typically another argument defining the string length. You may try to guess it's format, probably it is additional int
as a last argument.
I would make another Fortran wrapper, that would take an int
with length and an array of chars of length length
preferably without the trailing \0
.
logical function f_wrap(handle, name, length) bind(C,name="f_wrap")
use iso_c_binding
integer(c_int),value :: handle
integer(c_int),value :: length
character(1,kind=c_char),intent(in) :: name(length)
character(length) :: tmp
tmp = name
f_wrap = f_fn(int(handle), tmp)
end function
The tmp
may be unnecessary, because the binary representation is the same, just try it.