[Rd] C Interface

Dirk Eddelbuettel edd at debian.org
Sat Jun 19 04:37:47 CEST 2010


Michael,

You are getting confused in compiler minutia when you could be concentrating
on your code.  The inline package can help here.  

Consider the snippet below which loads inline, defines your function body
sans headers etc and then uses the magic of inline to compile, link and load
your function:

-----------------------------------------------
library(inline)

code <- '
  SEXP result;
  PROTECT(result = NEW_NUMERIC(1));
  double* ptr=NUMERIC_POINTER(result);
  double t = *REAL(s);
  double u = t-floor(t)-0.5;
  if(u>0) *ptr=-1+4*u; else *ptr=-1-4*u;
  Rprintf("The value is %f\\n", *ptr);
  UNPROTECT(1);
  return result;
'

fun <- cfunction(signature(s="numeric"), code)

fun(0.0001)
-----------------------------------------------

Pasted in my R session I get:

> library(inline)
> 
> code <- '
+   SEXP result;
+   PROTECT(result = NEW_NUMERIC(1));
+   double* ptr=NUMERIC_POINTER(result);
+   double t = *REAL(s);
+   double u = t-floor(t)-0.5;
+   if(u>0) *ptr=-1+4*u; else *ptr=-1-4*u;
+   Rprintf("The value is %f\\n", *ptr);
+   UNPROTECT(1);
+   return result;
+ '
> 
> fun <- cfunction(signature(s="numeric"), code)
> 
> fun(0.0001)
The value is 0.999600
[1] 0.9996
> 

(I added a newline which, given that the code is character string, needed to
be escaped.)

If you like inline, you may like it even more in conjunction with Rcpp as the
program becomes shorter and simpler thanks to as<>() and wrap():

> code <- '
+   double t = as<double>(s);
+   double u = t-floor(t)-0.5;
+   if (u>0) t=-1+4*u; else t=-1-4*u;
+   std::cout << "The value is " << t << std::endl;
+   return wrap(t);
+ '
> fun <- cxxfunction(signature(s="numeric"), code, plugin="Rcpp")
> 
> fun(0.0001)
The value is 0.9996
[1] 0.9996
> 

Rcpp has a few vignettes that help getting started.  The rcpp-devel list can
help with questions.

-- 
  Regards, Dirk



More information about the R-devel mailing list