Writing an R Package Calling C/C++ Functions
The following two references provide detailed instruction. Among other resources that can easily be found by google, these two seem to be the most useful to me.
- A note by Carlies Geyer. This explains how to call C/C++ (and Fortran) functions from R.
- A tutorial by Alan Lenarcic. This explains how to write an R package (in particular for a Windows system).
However, in addition I struggled a little bit to figure out
the following questions. I was working on a Windows system
and these problems might well disappear on a different system. The
discussion below is based on the knowledge of the two references
mentioned above. Basically, to call C/C++ functions,
- compile the C/C++ codes into a shared library (.dll in Windows and .so (.o) in linux),
- load the shared library by dyn.load("LIBNAME"), and
- call the compiled C function by .C("FUNNAME",...). Here LIBNAME is the name of the shared library file and FUNNAME is the name of the C function.
This part is clearly described in the two references mentioned above.
1. How to obtain returned values from C functions?
The C functions should have no return value. To return some values from
a C function to R, one should set an argument as the value passer.
Recall that in the C functions to be called by R, all the arguments are pointers. Therefore, the C functions should assign the to-be-returned value(s) to the value(s) pointed by this value-passer pointer.
2. How to call C++ functions?
One can have C++ functions in the source code (e.g. dealing with
sophisticated data structure that cannot be handled easily by C).
However, the function to be called from R must be of C extern format.
To call C++ functions from R, one should have
extern "C" {
void demoFunction(double *arg1, double *arg2) //all the arguments must be pointers.
{
// within the function, one can call other C++ functions though.
......
}
}
and then call demoFunction from R as usual by .C("demoFunction", as.double(arg1), as.double(arg2)).
3. How to build a package calling C/C++ functions?
Lenarcic's tutorial described clearly how to build an R package. But it
seems to me that to build an R package calling C/C++ functions, one
crucial step is missing in that tutorial (this might be due to the
difference of the systems and versions of the R). One needs to add the following R function:
.First.lib <- function(lib, pkg)
{
library.dynam("LIBNAME", pkg, lib)
}
in
the R files to be compiled. Otherwise I encountered an error when calling dyn.load(). The function .First.lib() is called when the package is loaded.
Updated January 21, 2013:
In the latest version (currently 2.15.2) of R, .First.lib no longer
exists and is replaced by .onLoad. (It took me a whole afternoon to
install the latest R, rebuild the entire package, and install the
package successfully in my computer: R and Rtools both need to be
updated, otherwise the same source code wouldn't pass R CMD check;
somehow surprisingly, I need to manually create this folder in
user/Documents/R/win-library/2.15 so that R CMD INSTALL can run
successfully...)