.Fortran(NAME, ..., NAOK=0, specialsok=F, COPY, CLASSES, DUP=T, PACKAGE=NULL) .C(NAME, ..., NAOK=F, specialsok=F, COPY, CLASSES, DUP=T, PACKAGE=NULL)
Details
section below.
Note in particular that all the arguments to the C procedure
must be pointers, and that character vectors in S-PLUS correspond
to
char**
declarations in C.
The length of the object passed in must be at least what the subroutine
expects; if not, expect memory faults and termination of the S-PLUS session.
The maximum number of "
...
" arguments is system-dependent; an error occurs
if your code requires more than the allowable number of arguments.
NAME
,
NAOK
,
specialsok
,
COPY
,
CLASSES
,
DUP
,
and
PACKAGE
,
or any prefix of them).
The corresponding component of the value
will have the same name (see below).
Arguments may be of any class that contains the desired vector;
in particular, they can be matrices or multi-way arrays.
The returned components will retain these attributes, although
the C or Fortran subroutine called will be ignorant of them.
TRUE
, then
NA
s are allowed in the arguments
to be passed to the C or Fortran subroutine.
If
FALSE
, S-PLUS checks all arguments for missing values before calling
the subroutine and generates an error if any
NA
s are present
in any argument.
TRUE
,
then the special values (
Inf
and
NaN
(Not a Number)
are allowed into the C or Fortran.
If
FALSE
,
S-PLUS checks all arguments for special values before calling
the subroutine and generates an error if any special values are present in
any argument.
Use
is.nan
to distinguish between Not a Number
and standard missing values.
...
.
Each
FALSE
element asserts
that the subroutine does not overwrite the corresponding argument,
so it is unnecessary to copy the data, thus saving memory.
Be very careful when using this argument; if you are wrong, the
subroutine may overwrite other data in your evaluation.
...
.
Each element specifies which kind of data the subroutine expects for the
corresponding argument.
Valid classes are the atomic vectors
(
"numeric"
,
"integer"
,
"single"
,
"character"
,
"complex"
,
"raw"
),
plus
"list"
for recursive objects.
You can also use some corresponding C or Fortran
data types (such as
"double"
)
if they are easier to remember.
The type is the type of a single element; the actual C argument is a pointer
to this type.
...
" arguments
(which is the list of arguments to the subroutine).
The values in the elements of the list will be the values given to
.Fortran
or
.C
,
unless the subroutine itself overwrites some of the values,
in which case the changed values will be returned.
Normally the subroutine
willoverwrite some of its arguments,
so that some computed results can be returned.
The returned components retain the class of the original,
with the included vector possibly modified by the subroutine.
For example, a supplied matrix will be returned as a matrix
with the same structure,
but possibly with modified data values.
The names attribute of the list will be the names
of the "
...
" arguments.
The S-PLUS storage modes
logical
,
character
,
integer
,
single
,
double
,
complex
correspond to the C types
long *
,
char **
,
long *
,
float *
,
double *
,
and
struct {double re,im;} *
and to the Fortran types
logical
,
character*(*)
,
integer
,
real
,
double precision
,
and
double complex
.
(
double complex
is a complex datum
comprised of double precision parts
and may not be available on some older Fortran compilers.)
You may pass a S-PLUS
list
to a C subroutine,
which should declare it
void **
--
it may be passed to a built-in C subroutine such as call_S
but your C subroutine should treat it as a pointer to an opaque object.
The work of coercing the arguments to the required data types can be
handled in three ways.
(1) The subroutine can be registered,
by a call to
setInterface
(see the documentation for that function).
(2) The
CLASSES
argument can be included
in the call to
.C
or
.Fortran
.
(3) The calling function can do whatever is needed for each argument.
This was the old convention, by which arguments were passed
inside coercion functions such as
as.double
.
The returned value of a C or Fortran function is lost, so all returned data must be passed back via the argument list. This is common practice in Fortran, but C functions often require a new C procedure which calls them and which uses pointers for arguments and passes back all data via the argument list.
S_alloc
allocates storage in a C function and
call_S
calls S-PLUS functions from a C function.
Only the first element of a vector of character strings is passed to Fortran subroutines.
# use a Fortran subroutine that takes a double precision array and its length function(x) { z <- .Fortran("mycalc", ans=x, length(x), COPY=c(T,F), CLASSES=c("numeric", "integer")) return(z$ans) }