Write a skeleton for adding native routine registration to a package.
package_native_routine_registration_skeleton(dir, con = stdout(),
align = TRUE, character_only = TRUE, include_declarations = TRUE)
Top-level directory of a package.
Connection on which to write the skeleton: can be specified as a file path.
Logical: should the registration tables be lined up in three columns each?
Logical: should only .NAME
arguments specified by character
strings (and not as names of R objects nor expressions) be extracted?
Logical: should the output include declarations (also known as ‘prototypes’) for the registered routines?
None: the output is written to the connection con
.
There are several tools available to extract function declarations from C or C++ code. For example,
For C code one can use cproto
(http://invisible-island.net/cproto/cproto.html; Windows
executables are available), for
example
cproto -I/path/to/R/include -e *.c
ctags
(commonly distributed with the OS)
covers C and C++., listing all function usages by something
like
ctags -x *.c
. (The ‘Exuberant’ version allows a lot more control.)
Registration is described in section 5.4.1 of ‘Writing R
Extensions’. This function produces a skeleton of the C code which
needs to be added to enable registration, conventionally as file
src/init.c
or appended to the sole C file of the package.
This function examines the code in the R
directory of the
package for calls to .C
, .Fortran
, .Call
and
.External
and creates registration information for those it can
make sense of. If the number of arguments used cannot be determined
it will be recorded as -1
: such values should be corrected.
Optionally the skeleton will include declarations for the registered
routines: they should be checked against the C/Fortran source code,
not least as the number of arguments is taken from the R code. For
.Call
and .External
calls they will often suffice, but
for .C
and .Fortran
calls the void *
arguments
would ideally be replaced by the actual types. Otherwise declarations
need to be included (they may exist earlier in that file if appending
to a file, or in a header file which can be included in
init.c
).
The default value of character_only
is appropriate when working
on a package without any existing registration: character_only =
FALSE
can be used to suggest updates for a package which has been
extended since registration. For the default value, if .NAME
values are found which are not character strings (e.g.names
or expressions) this is noted via a comment in the output.
Packages which used the earlier form of creating R objects for native
symbols via additional arguments in a useDynLib
directive will probably most easily be updated to use registration
with character_only = FALSE
.
If an entry point is used with different numbers of arguments in the
package's R code, an entry in the table (and optionally, a
declaration) is made for each number, and a comment placed in the
output. This needs to be resolved: only .External
calls can
have a variable number of arguments, which should be declared as
-1
.
A surprising number of CRAN packages had calls in R code to native routines not included in the package, which will lead to a ‘loading failed’ error during package installation when the registration C code is added.
Calls which do not name a routine such as .Call(…)
will be
silently ignored.