Skip to content

[Rcpp-devel] Pass an Rcpp module object to a method belonging to another module from R?

7 messages · Grant Brown, Dirk Eddelbuettel, Hao Ye +2 more

#
Hi folks,

I'm building several Rcpp modules which specify parts of a complicated
statistical model, and want to pass them to a main module for use. Is there
an easy way to do this?

Below is a simplified example, with question marks where I'm not sure what
to do. I've tried accepting a pointer to A, playing with using XPtrs, and a
bunch of things which made far less sense, but so far no luck.

Any suggestions or links to sections of the docs I should revisit would be
appreciated.

Thanks,
-Grant


## file: A.cpp

class A
{
public:
A();
~A();
};

class B
{
public:
B();
void DoSomethingWithInstanceOfA(???);
~B();
};

A::A()
{
// Do stuff
}

B::B()
{
// Do stuff
}

B::DoSomethingWithInstanceOfA(???)
{
// Do stuff
}

RCPP_MODULE(mod_A)
{
using namespace Rcpp;
class_<A>( "A" )
.constructor();
}

RCPP_MODULE(mod_B)
{
using namespace Rcpp;
class_<B>( "B" )
.constructor()
.method("DoSomethingWithInstanceOfA", &B::DoSomethingWithInstanceOfA);
}


### End pseduo c++ code
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20140909/55bebe3a/attachment.html>
#
On 9 September 2014 at 19:56, Grant Brown wrote:
| Hi folks,?
| 
| I'm building several Rcpp modules which specify parts of a complicated
| statistical model, and want to pass them to a main module for use. Is there an
| easy way to do this??
| 
| Below is a simplified example, with question marks where I'm not sure what to
| do. I've tried accepting a pointer to A, playing with using XPtrs, and a bunch
| of things which made far less sense, but so far no luck.?
| 
| Any suggestions or links to sections of the docs I should revisit would be
| appreciated.?

That's neat and somewhat ambitious. Not sure it can be done; Romain may have
pointers for you.

I prefer to keep things simple; at least initially.  I sometimes create a
larger class (possibly as a singleton) and then have accessors from R which
initialize, supply parameters, alter parameters, request computation, ... You
can then play with factories, and components, and inheritance, etc pp.

By keeping the interface simple I can set it up in a way which lets me test
the functionality also in a simple main away from R.  But that may just be me.

Dirk

 
| Thanks,
| -Grant
| 
| 
| ## file: A.cpp
| 
| class A
| {
| public:
| A();
| ~A(); ?
| };
| 
| class B
| {
| public:
| B();
| void DoSomethingWithInstanceOfA(???);
| ~B();
| };
| 
| A::A()
| {
| // Do stuff
| }
| 
| B::B()
| {
| // Do stuff
| }
| 
| B::DoSomethingWithInstanceOfA(???)
| {
| // Do stuff
| }
| 
| RCPP_MODULE(mod_A)
| {
| using namespace Rcpp;
| class_<A>( "A" )
| .constructor();
| }
| 
| RCPP_MODULE(mod_B)
| {
| using namespace Rcpp;
| class_<B>( "B" )
| .constructor()
| .method("DoSomethingWithInstanceOfA", &B::DoSomethingWithInstanceOfA);
| }
| 
| 
| ### End pseduo c++ code
| 
| 
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
#
Thanks for the feedback, I'll definitely consider those options.

My original motivation (besides the sheer convenience of Rcpp modules as a
way to move work into C++ land) was that there's a lot of data and model
specification information that needs to migrate from R user land to the
lower level library, and I didn't want the main model object to have to
keep track of too much state (or have too huge of a constructor).

My fallback should this prove unfeasible will probably be to put  together
an R layer which can collect and validate the requisite components before
providing them to the giant constructor.

Thanks!
On Tue, Sep 9, 2014 at 8:16 PM, Dirk Eddelbuettel <edd at debian.org> wrote:

            
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20140909/811ff38e/attachment.html>
#
Grant,

In my own work, I found that input validation is actually significantly
easier to do in R. (and even if you did do it in the c++ layer, informative
error messages should probably be thrown as exceptions back to R,
regardless.)

A giant constructor is not necessary either, as you can send data and
arguments to the c++ class through separate functions. This gives you some
flexibility if, say, you wanted to write different R wrapper functions
using the same underlying computational object.

My assumption, based on your original email, was that you were looking for
a use case where you might want to call separate computations on different
objects of class A from R (thus necessitating exposing A's functions to R),
but then also be able to do some computations in an object of class B that
could swap different objects of class A in and out. If that isn't the case,
then there's probably a simpler, if less elegant, implementation to do what
you want.

Best,
--
Hao Ye
hye at ucsd.edu
On Tue, Sep 9, 2014 at 6:47 PM, Grant Brown <grant.brown73 at gmail.com> wrote:

            
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20140909/79b173ac/attachment-0001.html>
#
This is once again something with which the RCPP_EXPOSED_CLASS macro can help with. Try adding 

RCPP_EXPOSED_CLASS(A)

before you declare class A and simply use this signature for the method. 

void DoSomethingWithInstanceOfA(const A& ) 

Also, you can have both of these classes in the same module you know; 

RCPP_MODULE(LemonCurry)
{
	using namespace Rcpp;

        class_<A>( "A" )
	    .constructor();

	class_<B>( "B" )
	    .constructor()
	    .method("DoSomethingWithInstanceOfA", &B::DoSomethingWithInstanceOfA);
}

Romain. 

PS: Having to resort to that sort of macros is one of the reason that made me remove modules from Rcpp11, which will be replaced by something that will be nicer to use later. 

Le 10 sept. 2014 ? 02:56, Grant Brown <grant.brown73 at gmail.com> a ?crit :
#
Gregory Jefferis
On 10 Sep 2014, at 10:39, Romain Francois <romain at r-enthusiasts.com> wrote:

            
I used this approach happily in the nabor package (on github) but the only caveat is that from R you need to call with something like:

A$method(B$.CppObject)

You can get some interesting crashes if you pass the R reference class (i.e. B) directly as the argument. I guess it might be better to have a derived R class that looks after extracting the .CppObject field. 

Best,

Greg.
#
Le 10 sept. 2014 ? 14:22, Gregory Jefferis <jefferis at mrc-lmb.cam.ac.uk> a ?crit :
That looks like a bug. Please submit it here: https://github.com/RcppCore/Rcpp/issues