External pointers with Rcpp

[This article was first published on Romain Francois, Professional R Enthusiast, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

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 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 their blog: Romain Francois, Professional R Enthusiast.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)