.BG
.FN call_S
.TL
Call S from a C Routine
.CS
call_S(func, nargs, arguments, modes,
       lengths, names, nres, results)
char *func;
char **arguments, **modes, **names, **results;
long nargs, *lengths, nres;
.AG func
a pointer to an S function.  This will have been passed through via
an argument in a `.C' call; e.g.,
.Cs
myfun <- function(x)x+1
\&.C("my_c_code",list(myfun),as.double(xx),
    as.integer(length(xx)))
.Ce
The C code in `my_c_code' before the call to `call_S' should just pass
this pointer around, not doing anything with it that might alter it.
.AG nargs
the number of arguments to be passed to the S function.
.AG arguments
an array of pointers to the data being passed to the S function.
These can point to any type of data, but must be cast to type `char *'
when put into `arguments':
.Cs
double *xarg;
 ...
arguments[0] = (char *)xarg;
.Ce
.AG modes
the modes of the arguments, as character strings containing the usual
S modes (see the table in section 7.2.3).
.AG lengths
the number of elements in each of the arguments to the S function.
.AG names
the names for the arguments to the S function, to be matched
against the argument names in the function definition.
`names' can be 0, as can any of `names[i]'.
If `names' is not 0 and `names[i]' is not 0, then `names[i]' is a
pointer to the character string in C to be used as the actual argument
name corresponding in the call to the S function.
.AG nres
the number of components of the value of the S function to be passed back
to C.
If `nres' is one and the function produces an atomic result (e.g., numeric),
this is passed back.  Otherwise, the S function is expected to produce
a list whose elements provide the results passed back.
If the actual number of results exceeds `nres', the rest are ignored; if
it is less than `nres', null pointers are returned in the corresponding
elements of `results'.
.AG `results'
a vector in which the pointers to the data in the components of the results
will be stuffed by `call_S'.  The data may be of any mode, but will be
cast to `char *' by `call_S'.  The calling routine will want to cast them
back to the desired type:
.Cs
double *yresult;
 ...
yresult = (double *)results[0];
.Ce
At the moment, the S function is responsible for assuring that the results
are of the right mode and length expected by the C code.
.PP
Note that the calling routine is responsible for allocating space for
all the arrays passed to `call_S'.
See `S_alloc' for storage allocation.
.EX
/*
 * A C routine that gets S to call a
 * function that expects a "double" vector
 * and returns a "double" vector, together
 * with its "integer" length.  The routine
 * then replaces x with the return value
 * (which should be no longer than x) and
 * returns the new length of x.
 */
long rev_test(func, x, nx)
char *func;
double *x;
long nx;
{
	long lengths[2], count, i;
	char *arguments[2], *values[2];
	char *modes[2], *names[2];
	double *xnew;

	arguments[0] = (char *)x;
	modes[0] = "double";
	lengths[0] = *nx;
	names[0] = "x";
	call_S(func, 2, arguments, modes,
		lengths, names, 2, values);
	xnew = (double *)values[0];
	count = *((long *)values[1]);
	for(i = 0; i < count; i++)
		*x++ = *xnew++;
	return(count);
}
.KW programming
.WR
