Skip to content
Prev 2172 / 10988 Next

[Rcpp-devel] Creating pointers to objects and wrapping them

Hello,

The approach here is to use a callback to the new function of R, to 
mimic the call :

b <- new( B, 0L )

which you can do for example using the Language class:

namespace Rcpp {
     template <>
     SEXP wrap( const B& object ){
         Language call( "new", Symbol( "B" ), object.get_i() ) ;
         return call.eval() ;
     }
}

Now, for Rcpp classes to be aware of a custom wrap, you need some 
gymnatics, as described in the Rcpp-extending vignette.
You need to include RcppCommon.h first, define you class and declare the 
custom wrap, then include Rcpp.h, then define you wrap.

I'm pasting a full pass at it below. Consider using the verbose = TRUE 
argument of cxxfunction to see what C++ code is being generated.

Things will get much simpler when we figure out a way to return classes 
exposed by modules and implement it.

Romain


require( inline )
require( Rcpp )

settings <- getPlugin("Rcpp")
settings$includes <- sprintf( "%s\n%s",
'
#include <RcppCommon.h>
// B just stores an integer i here
class B {
   public:
     B(int i) : i(i) {}

     int get_i() const {
       return i;
     }

   private:
     int i;
}  ;
namespace Rcpp{
     template <>
     SEXP wrap( const B& object ) ;
}
',
settings$includes
     )

inc <- '
namespace Rcpp {
     template <>
     SEXP wrap( const B& object ){
         Language call( "new", Symbol( "B" ), object.get_i() ) ;
         return call.eval() ;
     }
}

// A contains a vector v of pointers to B
class A {
   public:
     A(int n) : v(n) {}

     // THIS IS THE METHOD I WOULD LIKE TO IMPLEMENT:
     SEXP foo(int j) {
       if (!v[j]) {
         v[j] = new B(j);
       }

       // THIS DOES NOT WORK:
       return wrap(*v[j]);
     }

   private:
     std::vector<B*> v;
} ;

// Rcpp module exposing both A and B
RCPP_MODULE(MyModule) {
   class_<A>( "A" )
     .constructor<int>(
             "Create an instance of A with a given number of pointers")
     .method("foo",
             &A::foo,
             "(Create and) get one of the objects of type B.")
   ;

   class_<B>( "B" )
     .constructor<int>("Create an instance of B from an int.")
     .property("i",
               &B::get_i)
   ;
}
'

fx <- cxxfunction( , '

', includes = inc, settings = settings )
populate( Module( "MyModule", getDynLib( fx ) ), env = .GlobalEnv )

a <- new (A, 5)
b <- a$foo(0)
b$i







Le 18/04/11 16:12, schattenpflanze at arcor.de a ?crit :