[Rcpp-devel] c++ class as argument in rcpp function (using modules)

Dirk Eddelbuettel edd at debian.org
Wed Dec 21 23:54:25 CET 2011


On 21 December 2011 at 16:29, Douglas Bates wrote:
| On Wed, Dec 21, 2011 at 3:55 PM, Yasir Suhail <yusuhail at gmail.com> wrote:
| > Hi
| >
| > I looked up the previous thread "Creating pointers to objects and wrapping
| > them"
| > from http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-April/002170.html,
| > and it seems that providing a specialization of the wrap<>() function can
| > help us return classes. Perhaps similarly, one could provide a
| > specialization of the as<>() function for arguments? While wrap is
| > implemented with the Language("new" ... function, is there any example of an
| > as<>() specialization for custom classes? The vignette
| > (http://dirk.eddelbuettel.com/code/rcpp/Rcpp-extending.pdf) shows a
| > declaration for as, but no definitions.
| 
| It is not clear if you want to wrap the pointer to the object as an
| "external pointer" in R or if you want to create an R object from your
| C++ object.  Wrapping an external pointer is straightforward.  This
| example from http://r-forge.r-project.org/scm/viewvc.php/pkg/lme4Eigen/src/external.cpp?view=markup&root=lme4
| 
|     // generalized linear model (and generalized linear mixed model) response
| 
|     SEXP glm_Create(SEXP fam, SEXP y, SEXP weights, SEXP offset, SEXP mu,
| 		    SEXP sqrtXwt, SEXP sqrtrwt, SEXP wtres, SEXP eta, SEXP n) {
| 	BEGIN_RCPP;
| 	glmResp *ans = new glmResp(List(fam), y, weights, offset, mu,
| 				   sqrtXwt, sqrtrwt, wtres, eta, n);
| 	return wrap(XPtr<glmResp>(ans, true));
| 	END_RCPP;
|     }
| 
|     SEXP glm_setN(SEXP ptr_, SEXP n) {
| 	BEGIN_RCPP;
| 	XPtr<glmResp>(ptr_)->setN(as<MVec>(n));
| 	END_RCPP;
|     }
| 
| shows wrapping an external pointer to return it and then passing the
| external pointer to be modify the C++ object.  You should be aware,
| however, that an external pointer cannot be save'd then loaded into
| another R session (which makes sense if you think about it).  You need
| to do a bit of dancing if you want to do that.  Essentially you must
| save as R objects enough information to regenerate the C++ object then
| detect if the external pointer points to NULL and regenerate the
| object if it does.

Very nice.  

In the same spirit, the email by Richard Downe was also good, but maybe a
little misleading (or maybe I am just tired and misread...).  In essence it
showed an "object factory" which given a string returned a new object.  

You can combine this with external pointers which makes it transparent in our
context as external pointers can seamlessly travel back and forth between R
and C++ as we have Rcpp::XPtr wrapping the corresponding SEXP.

Dirk

-- 
"Outside of a dog, a book is a man's best friend. Inside of a dog, it is too
dark to read." -- Groucho Marx


More information about the Rcpp-devel mailing list