7.1 Introduction
These
routines allow C-language subroutines to use character strings passed in from a
FORTRAN routine (CHARACTER*n data type). FORTRAN-callable subroutines written
in C must use these routines to handle character strings. The passing of
strings between FORTRAN and C varies widely among different machine
architectures. Attempting to do your own without using these routines
practically guarantees that your code will not be portable.
These
routines are most useful in the FORTRAN interface to SUBLIB routines, but they
could be useful within a single application program if it uses both languages.
All
of these routines are callable from C only. Do not} attempt to call them from
FORTRAN. Writing a FORTRAN routine that accepts C strings is much more
difficult. See
2.6
Mixing FORTRAN and C.
These
routines have much in common in their calling sequences, so the common features
and rules are described only once in the Common Features section below.
Two
of the routines apply only to strings being sent out of a C routine, back to
the FORTRAN caller. They are marked “output” below. The other four
apply only to strings being passed in to a C routine, from a FORTRAN caller.
They are marked “input''.
7.1.1 Common
Features: Rules and arguments common to all string routines
All
the string conversion routines place great emphasis on the argument list of the
C routine that is directly called by FORTRAN. Certain rules apply to that
argument list, and many of the common parameters reference it. All of these
apply to the routine called directly} by FORTRAN. Suppose a FORTRAN routine
calls routine a(), which then calls routine b(), and b() wants to call one of
these string conversion routines. All of the parameters and rules will apply
only to a()'s argument list. Routine b() will need much of the information
passed in from a() in order to call the string conversion routines, but all the
information is relative to a()'s argument list. In general, it's usually easier
to have a() do all the conversion and let b() deal only with C strings, but
sometimes that is impractical.
7.1.1.1 Include
file
In
order to use any of the routines, you must include the file
“ftnbridge.h”. As with other RTL includes, you must include
xvmaininc.h first, the names must be enclosed in double quotes and end in the
“.h” extension (you don't need xvmaininc.h if
“vicmain_c” is included). Example:
#include "xvmaininc.h"
#include "ftnbridge.h"
7.1.1.2 Imakefile
The
flag FTN_STRING must be defined in the imakefile for the program unit if any C
routine accepts FORTRAN strings. This applies to both the direct-called
routine, and the routine that ultimately calls one of the conversion routines.
The FTN_STRING flag causes the compiler to use a lower level of optimization,
which is required on some machines in order to access the argument list.
7.1.1.3 FORSTR_PARAM
and FORSTR_DEF macros
In
most routines (see below for exception), include the macro FORSTR_PARAM in the
argument list of the directly called routine, FORSTR_DEF at the end of the
formal parameter declaration list, just before the opening brace of the
procedure and FORSTR_BLOCK immediately after the opening brace of the function
with no other declarations or statements before it.
FORSTR_DEF
and FORSTR_BLOCK should not have semicolons after them, as the semicolon (if
needed) is included in the macro definition. These macros are no-ops on many
machines, but are required on some in order to get at the FORTRAN string lengths.
The
exception is routines that use the <varargs.h> variable argument
mechanism. User subroutines should not normally use varargs, but it is used
fairly extensively inside the RTL to handle the keyword-value argument pairs.
If you use <varargs.h>, follow all the standard C rules for that
mechanism, and you should not use the FORSTR_PARAM, FORSTR_BLOCK or FORSTR_DEF
macros. For example:
FTN_NAME(text)(inbuf, inchr, line, outbuf, size, dn, FORSTR_PARAM)
char *inbuf;
int *inchr, *line;
unsigned char outbuf[];
int *size, *dn;
FORSTR_DEF
{
FORSTR_BLOCK
char *c_string;
int length,i;
...
7.1.1.4 Argument
restrictions
All
arguments to the direct-called routine must be the size of a generic pointer.
Since FORTRAN passes everything by reference anyway, all of your arguments will
be pointers, so this should not cause a problem.
7.1.1.5 Arguments
to FORTRAN string conversion routines
The
arguments to the FORTRAN string conversion routines all apply to the argument
list of the routine that is directly called by FORTRAN, not to any intermediary
routines.
- FOR_STRING:
pointer to char, input/output
FOR_STRING
should be the name of the argument that contains the FORTRAN string. It should
be declared as type “char *” in the argument list. Simply pass in
the name of the argument, without any extra \&'s or *'s or anything. The
FORTRAN routine must declare the string as CHARACTER*n. String arrays (handled
with the routines
sc2for_array}
and
sfor2c_array}
must be declared as single-dimension arrays of CHARACTER*n, but are still
declared as “char *” in the C routine.
- ARGPTR:
generic pointer, input
ARGPTR
should be the address of the first argument, whatever it is. It does not matter
what the data type of the first argument is, or if it is already a pointer to
something else. Simply put an ampersand (\&) followed by the name of the
first argument in the argument list.
- NARGS:
integer, input
NARGS
is simply the total number of arguments passed in to the routine. Do not} count
FORSTR_PARAM as one of the arguments. If you are using <varargs.h>, pass
in the actual number of arguments sent to the routine.
- ARGNO:
integer, input
ARGNO
is the number of the argument that contains the string to be converted. If the
string is the first argument in the list, ARGNO would be 1. If it is the fifth
argument, ARGNO would be 5.
- STRNO:
integer, input
STRNO
is the string count for the string to be converted. It is similar to ARGNO, but
counts only strings. So, if the string you are converting is the third
argument, but only the second string in the argument list (because the first
one is an integer), then ARGNO would be 3 but STRNO would be 2.
Some
examples may help to clarify things. The routine
sfor2c
is used in these examples, but the principles apply to all the string
conversion routines. The calling sequence for
sfor2c}
is
sfor2c(c_string,
max_length, for_string, argptr, nargs, argno, strno).
int constargs(a, s1, s2, b, FORSTR_PARAM)
int *a, *b;
char *s1, *s2;
FORSTR_DEF
{ char cs1[11], cs2[20];
sfor2c(cs1, 10, s1, &a, 4, 2, 1);
sfor2c(cs2, 19, s2, &a, 4, 3, 2);
}
int constargs2(s1, s2, a, s3, b, s4, FORSTR_PARAM)
char *s1, *s2, *s3, *s4;
int *a, *b;
{ char cs1[101], cs2[31], cs3[80], cs4[5];
sfor2c(cs1, 100, s1, &s1, 6, 1, 1);
sfor2c(cs2, 30, s2, &s1, 6, 2, 2);
sfor2c(cs3, 79, s3, &s1, 6, 4, 3);
sfor2c(cs4, 4, s4, &s1, 6, 6, 4);
}
int varargs(va_alist)
va_dcl
{ char cs[11];
/* nargs = number of arguments, argno=argument #, and strno=string # */
/* which all come from knowing what to expect in the argument list */
forstr = va_arg(ap, char *);
sfor2c(cs, 10, forstr, &va_alist, nargs, argno, strno);
}