External pointers with Rcpp

January 8, 2010
By

(This article was first published on Romain Francois, Professional R Enthusiast, and kindly contributed to R-bloggers)

One of the new features of Rcpp is the XPtr class template, which lets you treat an R external pointer as a regular pointer. For more information on external pointers, see Writing R extensions.

To use them, first we need a pointer to some C++ data structure, we'll use a pointer to a vector<int> :

/* creating a pointer to a vector<int> */
std::vector<int>* v = new std::vector<int> ;
v->push_back( 1 ) ;
v->push_back( 2 ) ;

Then, using the XPtr template class we wrap the pointer in an R external pointer

/* wrap the pointer as an external pointer */
/* this automatically protected the external pointer from R garbage 
   collection until p goes out of scope. */
Rcpp::XPtr< std::vector<int> > p(v, true) ;

The first parameter of the constructor is the actual (sometimes called dumb) pointer, and the second parameter is a flag indicating that we need to register a delete finalizer with the external pointer. When the external pointer goes out of scope, it becomes subject to garbage collection, and when it is garbage collected, the finalizer is called, which then calls delete on the dumb pointer.

Wrapping it all together thanks to the inline package, here's a function that creates an external pointer to a vector<int> and return it to R

        funx <- cfunction(signature(), '
                /* creating a pointer to a vector<int> */
                std::vector<int>* v = new std::vector<int> ;
                v->push_back( 1 ) ;
                v->push_back( 2 ) ;
                
                /* wrap the pointer as an external pointer */
                /* this automatically protected the external pointer from R garbage 
                   collection until p goes out of scope. */
                Rcpp::XPtr< std::vector<int> > p(v, true) ;
                
                /* return it back to R, since p goes out of scope after the return 
                   the external pointer is no more protected by p, but it gets 
                   protected by being on the R side */
                return( p ) ;
        ', Rcpp=TRUE, verbose=FALSE)
        xp <- funx()

At that point, xp is an external pointer object

> xp
<pointer: 0x9c850c8>
> typeof( xp )
[1] "externalptr"

Then, we can pass it back to the C(++) layer, an continue to work with the wrapped stl vector of ints. For this we use the other constructor for the XPtr class template, that takes an R object (SEXP) of sexp type EXTPTRSXP.


/* wrap the SEXP as a smart external pointer */
Rcpp::XPtr< std::vector<int> > p(x) ;

/* use p as a 'dumb' pointer */
p->front() ;

Again, we can wrap this up for quick prototyping using the inline package :

        # passing the pointer back to C++
        funx <- cfunction(signature(x = "externalptr" ), '
                /* wrapping x as smart external pointer */
                /* The SEXP based constructor does not protect the SEXP from 
                   garbage collection automatically, it is already protected 
                   because it comes from the R side, however if you want to keep 
                   the Rcpp::XPtr object on the C(++) side
                   and return something else to R, you need to protect the external
                   pointer, by using the protect member function */
                Rcpp::XPtr< std::vector<int> > p(x) ;
                
                /* just return the front of the vector as a SEXP */
                return( Rcpp::wrap( p->front() ) ) ;
        ', Rcpp=TRUE, verbose=FALSE)
        front <- funx(xp)
> front
[1] 1

The example is extracted from one unit tests that we use in Rcpp, see the full example :

> system.file( "unitTests", "runit.XPTr.R", package = "Rcpp" )
[1] "/usr/local/lib/R/library/Rcpp/unitTests/runit.XPTr.R"

See also the announcement for the release of Rcpp 0.7.1 here to get a list of new features, or wait a few days to see version 0.7.2.

Using the XPtr class template is the bread and butter of the CPP package I blogged about here

To leave a comment for the author, please follow the link and comment on his blog: Romain Francois, Professional R Enthusiast.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...



If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Tags: , , ,

Comments are closed.