Hello,

Currently, when exposing a c++ class to R through a Rcpp module, e.g:

class World {
public:
    World() : msg("hello"){}
    void set(std::string msg) { this->msg = msg; }
    std::string greet() { return msg; }

private:
    std::string msg;
};

void clearWorld( World* w){
        w->set( "" ) ;
}

RCPP_MODULE(yada){
        using namespace Rcpp ;
        
        class_<World>( "World" )
                .method( "greet", &World::greet )
                .method( "set", &World::set )
                .method( "clear", &clearWorld )
        ;
}



On the R side, we do :

# grab the module and the class
yada <- Module( "yada" )
World <- yada$World

# create an instance and play with it
w <- new( World )
w$greet()


The "w" object is of class "C++Object":

> class( w )
[1] "C++Object"
attr(,"package")
[1] "Rcpp"

> str( w )
Formal class 'C++Object' [package "Rcpp"] with 3 slots
  ..@ module  :<externalptr>
  ..@ cppclass:<externalptr>
  ..@ pointer :<externalptr>

The "C++Object" class contains all the information that is needed internally to dispatch to the internal method : pointer to its module, pointer to its class wrapper and pointer to the actual object.



However, I think one of the next step would be for the user to define S4 methods for C++ classes, i.e it would be nice to be able to do something like:

setMethod( "show", "World", function( object ){
        writeLines( object$greet() )
} )

but right now we cannot because there is no S4 class "World", all c++ objects share the R class "C++Object".

This is the context of this question. I need help for this.

Options I am thinking about:

1) when the module is loaded, we define a "World" class that extends "C++Object", i.e :

setClass( "World", contains = "C++Object" )

this would probably be the most natural way for the user. I am not sure where to store that class. should I create a new environment for the module, ...


2) make the dispatch internal, something like:

setInternalMethod( "show", World, function(object){
        writeLines( object$greet() )
} )

so that :
  - it registers an S4 "show" method for the "C++Object" class
- we maintain internally some sort of lookup table to find the show method for the internal class.




We have the same problem in rJava where all java references have the class "jobjRef", which makes it hard to do R side dispatch based on the java class. I've used something like option 2 with rJava and the RImageJ package once but I think option 1 is better and more natural.

It is probably more difficult to achieve option 1 with rJava because since java has reflection, we get all classes for free, where we need to specifically declare which ones with expose with Rcpp modules.



Anyway, I'm not asking for help in the C++ side, I realize this is crazy. But some R-level help would be welcome.

Romain


--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/9CQ66r : RMetrics 2010
|- http://bit.ly/cork4b : highlight 0.1-8
`- http://bit.ly/bklUXt : RcppArmadillo 0.2.1

_______________________________________________
Rcpp-devel mailing list
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to