Hi,
This has to be a basic question, but I cannot figure out what I am missing nor see quite similar pre-existing posts.
I am trying to create an Rcpp module around a class (generated C++ proxy class). The environment is Rcpp 0.10.5 on Windows, R 3.0.2 x64 and RTools 3.0.
R CMD INSTALL spits the dummy at compilation(?) time when the Exporter things kick in, with the message " cannot convert 'SEXP' to 'const std::vector<double>*' in initialization" on the 'Play' method as per below.
class SimulationExport {
public:
SimulationExport();
~SimulationExport();
void Execute(void);
void Play(const char* name, const std::vector<double>* values);
// other methods snipped
}
RCPP_MODULE(SimulationEx){
class_<SimulationExport>( "Simulation" )
// snipped
.method( "play", &SimulationExport::Play)
// snipped
}
I don't get why it cannot wrap a vector<double> given how similar it is to "7.2.2.7 Full Example" in the " Seamless R and C++ Integration with Rcpp" book. The same sample code created with Rcpp.package.skeleton compiles (though it fails check on load, BTW). The only difference is the presence of a 'const' modifier before the vector, but removing it does not solve the issue.
Rcpp.package.skeleton('sampleRcpp', module=TRUE, author='J-M')
library(devtools)
check('sampleRcpp') # passes past the compilation step.
Cheers,
J-M
[Rcpp-devel] Exporter.h cannot convert 'SEXP' to 'const std::vector<double>*' in initialization
4 messages · Jean-Michel.Perraud at csiro.au, Dirk Eddelbuettel, Romain Francois
Salut Jean-Michel,
On 23 October 2013 at 04:12, Jean-Michel.Perraud at csiro.au wrote:
| Hi,
|
| This has to be a basic question, but I cannot figure out what I am missing nor see quite similar pre-existing posts.
|
| I am trying to create an Rcpp module around a class (generated C++ proxy class). The environment is Rcpp 0.10.5 on Windows, R 3.0.2 x64 and RTools 3.0.
|
| R CMD INSTALL spits the dummy at compilation(?) time when the Exporter things kick in, with the message " cannot convert 'SEXP' to 'const std::vector<double>*' in initialization" on the 'Play' method as per below.
This is tricky. In essence, the template 'magic' needs to have a match for each
of types you supply. And you get a failure here.
That can mean two things (at least). We may have bug and something that
should work does not work. Or you requested something that simply is not
implemented.
As you get more experienced with this, you learn to differentiate the case
more quickly. In a nutshell, it is the second case here as you wished
something was implemented that simply isn't.
My preferred approach is too simplify and to use inline or attributes to try
something simpler.
Eg these work (first is a little nonsensical):
R> cppFunction("const std::vector<double> foo() { std::vector<double> x(3); return(x); }")
R> foo()
[1] 0 0 0
R> cppFunction("std::vector<double> foo2() { std::vector<double> x(3); return(x); }")
R> foo2()
[1] 0 0 0
R>
But as soon as you add a '*' for pointer to vector (which is an odd notion
anyway, you'd rather use a reference (but then you can't in a return value))
it blows up.
So in short, your code had a design issue. Make it
void Play(const char* name, const std::vector<double> & values);
and you should be fine:
R> cppFunction("int foo3(const std::vector<double> & x) { return(x.size()); }")
R> foo3(rnorm(3))
[1] 3
R> cppFunction("int foo4(std::vector<double> & x) { return(x.size()); }")
R> foo4(rnorm(3))
[1] 3
R> cppFunction("int foo5(std::vector<double> x) { return(x.size()); }")
R> foo5(rnorm(3))
[1] 3
R>
Hope this helps, Dirk
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
Le 23/10/2013 06:12, Jean-Michel.Perraud at csiro.au a ?crit :
Hi,
This has to be a basic question, but I cannot figure out what I am missing nor see quite similar pre-existing posts.
I am trying to create an Rcpp module around a class (generated C++ proxy class). The environment is Rcpp 0.10.5 on Windows, R 3.0.2 x64 and RTools 3.0.
R CMD INSTALL spits the dummy at compilation(?) time when the Exporter things kick in, with the message " cannot convert 'SEXP' to 'const std::vector<double>*' in initialization" on the 'Play' method as per below.
class SimulationExport {
public:
SimulationExport();
~SimulationExport();
void Execute(void);
void Play(const char* name, const std::vector<double>* values);
// other methods snipped
}
RCPP_MODULE(SimulationEx){
class_<SimulationExport>( "Simulation" )
// snipped
.method( "play", &SimulationExport::Play)
// snipped
}
I don't get why it cannot wrap a vector<double> given how similar it is to "7.2.2.7 Full Example" in the " Seamless R and C++ Integration with Rcpp" book. The same sample code created with Rcpp.package.skeleton compiles (though it fails check on load, BTW). The only difference is the presence of a 'const' modifier before the vector, but removing it does not solve the issue.
Rcpp.package.skeleton('sampleRcpp', module=TRUE, author='J-M')
library(devtools)
check('sampleRcpp') # passes past the compilation step.
Cheers,
J-M
As Dirk said, don't use a pointer to a std::vector<double>. What do you do in Play with this vector ? Why did you want to pass it as a pointer ? If this was for performance, then passing a reference won't cut it because Rcpp cheats and when you pass a reference as a parameter to a function that is Rcpp::export'ed, what happens is that the data gets copied. Could you instead pass down an NumericVector ? The reason is that given Rcpp's design, copy semantics of NumericVector are cheap (no data copy). Which leads back to hte original question: what does Play want to do with this vector ? Romain
Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30
Hi Dirk,
Thank you for the sound advice to simplify and test with cppInline. That indeed helps check what works or not for as<> and wrap<>.
Re-reading with a clearer head your book section on what can be wrapped by a call to _class.method(...), I figured out that I could use something like follows
void PlaySimEx(SimulationExport* simul, const char* name, Rcpp::NumericVector values)
{
const numvec v = Rcpp::as<numvec>(values);
simul->Play(name, &v);
}
All seems to work as expected.
I think I have a proof of concept C++/Rcpp wrapper generator for Fortran 2003/2008; I'll try to share it on github in a few weeks.
From: Dirk Eddelbuettel [edd at debian.org]
Sent: Thursday, October 24, 2013 2:37 PM
To: Perraud, Jean-Michel (CLW, Black Mountain)
Cc: rcpp-devel at lists.r-forge.r-project.org
Subject: Re: [Rcpp-devel] Exporter.h cannot convert 'SEXP' to 'const std::vector<double>*' in initialization
Sent: Thursday, October 24, 2013 2:37 PM
To: Perraud, Jean-Michel (CLW, Black Mountain)
Cc: rcpp-devel at lists.r-forge.r-project.org
Subject: Re: [Rcpp-devel] Exporter.h cannot convert 'SEXP' to 'const std::vector<double>*' in initialization
Salut Jean-Michel,
On 23 October 2013 at 04:12, Jean-Michel.Perraud at csiro.au wrote:
| Hi,
|
| This has to be a basic question, but I cannot figure out what I am missing nor see quite similar pre-existing posts.
|
| I am trying to create an Rcpp module around a class (generated C++ proxy class). The environment is Rcpp 0.10.5 on Windows, R 3.0.2 x64 and RTools 3.0.
|
| R CMD INSTALL spits the dummy at compilation(?) time when the Exporter things kick in, with the message " cannot convert 'SEXP' to 'const std::vector<double>*' in initialization" on the 'Play' method as per below.
This is tricky. In essence, the template 'magic' needs to have a match for each
of types you supply. And you get a failure here.
That can mean two things (at least). We may have bug and something that
should work does not work. Or you requested something that simply is not
implemented.
As you get more experienced with this, you learn to differentiate the case
more quickly. In a nutshell, it is the second case here as you wished
something was implemented that simply isn't.
My preferred approach is too simplify and to use inline or attributes to try
something simpler.
Eg these work (first is a little nonsensical):
R> cppFunction("const std::vector<double> foo() { std::vector<double> x(3); return(x); }")
R> foo()
[1] 0 0 0
R> cppFunction("std::vector<double> foo2() { std::vector<double> x(3); return(x); }")
R> foo2()
[1] 0 0 0
R>
But as soon as you add a '*' for pointer to vector (which is an odd notion
anyway, you'd rather use a reference (but then you can't in a return value))
it blows up.
So in short, your code had a design issue. Make it
void Play(const char* name, const std::vector<double> & values);
and you should be fine:
R> cppFunction("int foo3(const std::vector<double> & x) { return(x.size()); }")
R> foo3(rnorm(3))
[1] 3
R> cppFunction("int foo4(std::vector<double> & x) { return(x.size()); }")
R> foo4(rnorm(3))
[1] 3
R> cppFunction("int foo5(std::vector<double> x) { return(x.size()); }")
R> foo5(rnorm(3))
[1] 3
R>
Hope this helps, Dirk
--
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com