Mix C-string and fortran-string in one file
I have one question with mixing C-string and fortran-string in one file.
Supposed I am playing with the name string with fixed length 9, I define a length Macro like
#def开发者_C百科ine NAME_LEN 9
in a .c file.
There is an existing fortran-function, let's name it fortran_function(char* name)
Now I have to call this fortran function in a c function, let's name is
c_function(char name[]) {
fortran_function(name)
}
Now the problem is, how should I declare the c_function signature?
c_function(char name[])
c_function(char name[NAME_LEN +1])
or
c_function(char name[NAME_LEN])
Under what situations, I should use 9 as name length or 10?
My understanding is that, as long as you passed a null-terminated string with 9 characters to the c_function, all the declaration are correct. Is that right?
Any other concern should be put here? Any potential bugs?
There's one more gotcha here, if I remember correctly. Fortran does not use null-terminated strings; instead, it pads the right end of the buffer with 0x20 (space). So, if you have access to the Fortran source, I would modify the function signature to take the length of the passed-in string as an argument. Otherwise, you will probably crash the Fortran side of the code.
Dave is correct, the standard Fortran concept for strings is fixed-length, padded with blanks on the right. (Fortran now also have variable length strings, but these are not yet common and would be very tricky to inter-operate with C.) If you want the lengths fixed, then have the same parameter NAME_LEN in your Fortran code, with the same value. Dave's suggestion of an additional length argument is probably better.
An additional refinement is to use the ISO C Binding facility on the Fortran side (corrected per the comment!)
subroutine Fort_String_code (my_string), bind (C, name="Fort_String_code")
use iso_c_binding
integer, parameter :: NAME_LEN = 9
character (kind=c_char, len=1), dimension (NAME_LEN), intent (inout) :: my_string
etc. The "bind" name is the name by which C can call the Fortran routine -- it can be different from the Fortran name. Also provided as part of the iso_c_binding is the symbol C_NULL_CHAR which you can use in the Fortran code to provide the terminating null character that C expects, etc.
There's no difference to those calls. The c compiler will treat them all as char*. You just have to make sure you null terminate it before you use it in c. If you're only using the string in the fortran side and the c functions are just holding on to it, then you don't need to do anything.
精彩评论