Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
In Win32, Fortran by default passes a hidden length argument for strings. This argument is easily accessible to other languages, unlike the string-length information passed in 16-bit versions of Fortran. The hidden length argument consists of an unsigned 4-byte integer, always passed by value, immediately following the character string argument.
For example, if a Fortran program sets up the following call to a routine, Pass_Str
, implemented in C:
INTERFACE TO SUBROUTINE Pass_Str (string)
CHARACTER*(*) string
END
Then the C routine must expect two arguments:
void __stdcall PASS_STR (char *string, unsigned int length_arg )
Another important difference is in the format of the strings themselves. C strings are null-terminated. For example, given the following assignment:
Char *cstring="C text string";
The string data is stored as shown in the following figure.
Fortran strings are not null-terminated, and they are padded with blank spaces when assigned string data that is shorter than the declared length. For example, given the following assignment:
CHARACTER*14 forstring
DATA FORSTRING /"Fortran STRING'/
The string data is stored as follows. Note that if the string were any longer, it would be padded with trailing blanks.
A more efficient approach, wherever possible, is to adopt C string behavior. When the C or STDCALL attribute is applied to a routine, Fortran does not pass a hidden length argument. Furthermore, you can use the C-string feature to assign null-terminated string data in Fortran, as follows:
CHARACTER*20 forstring
DATA forstring /'This is a string'C/
The string variable, forstring
, can then be passed to a C routine. If the C or STDCALL attribute is used, Fortran passes forstring just as C does: pushing the address of a null-terminated string onto the stack, with no hidden length argument.
Note Fortran functions of type CHARACTER*(*) place a hidden string argument at the beginning of the parameter list; this may include both string address and length, as appropriate. C functions that implement such a call from Fortran must declare this hidden string argument explicitly and use it to return a value. However, you are more likely to avoid errors by not using character-string return types. Use subroutines whenever possible.
The following example demonstrates how a Fortran main program calls a C function that translates a string to all-uppercase. Because the string is passed by reference, there is no need to use a string return type. Note that the C attribute stops Fortran from passing a hidden string-length argument, and the DATA statement uses a āCā to specify null termination.
C File FORMAIN.FOR
C
INTERFACE TO SUBROUTINE Ucase [C,ALIAS:'_Ucase'] (text)
CHARACTER*(*) text [REFERENCE]
END
CHARACTER*40 forstring
DATA forstring /'This is a sample string.'C/
WRITE (*, *) forstring
CALL Ucase (forstring)
WRITE (*, *) forstring
END
/* File CSTR.C */
#include <ctype.h>
void Ucase( char *string )
{
char *ptr;
for (ptr = string; *ptr; ptr++)
*ptr = toupper( *ptr );
}
This use of C strings is usually the best approach, because most C library functions, as well as API functions, assume null-termination. However, if you use C to write string-manipulation functions, it is a good idea to translate null-terminated strings back into blank-padded strings after the C function returns. The following code performs this operation:
SUBROUTINE Fix_C_Str (text, length)
CHARACTER*(*) text
INTEGER*4 length
INTEGER*4 i
C Find the first null ('\0')
i = 1
DO WHILE ((i .LE. length) .AND. (text(i:i) .NE. '\0'))
i = i + 1
END DO
C Pad with blanks to the end of the string
DO WHILE (i .LE. length)
text (i:i) = ' '
END DO
END