[Rcpp-devel] c++ class as argument in rcpp function (using modules)
Dirk Eddelbuettel
edd at debian.org
Sat Dec 24 00:38:22 CET 2011
On 23 December 2011 at 18:16, Yasir Suhail wrote:
| Hi,
|
| I think I have figured out why we were getting the error. When we call the
| function from R, the type of the instance passed is S4SXP, rather than
| EXTPTRSXP, which is what XPtr(SEXP) expects.
That's possible.
| We can, however, use the Rcpp::S4
| (SEXP) constructor to get an S4 object. Are the user defined C++ classes
| derived from Rcpp::S4 classes?
|
| I don't know if there is still interest in this, so I don't know if I should
| keep filling your inboxes.
I think there is, but not everybody uses Rcpp modules all that actively so
that you may have a limited audience.
But extending Rcpp modules, and/or documenting it better, is definitely on
the TODO list so you are on the right track.
Dirk
| Thanks!
|
| On Thu, Dec 22, 2011 at 9:18 PM, Yasir Suhail <yusuhail at gmail.com> wrote:
|
| Hi,
|
| Dirk, thanks for uploading the next version, because it does sort of help
| here. The error now with Rcpp 0.9.8 is "expecting an external pointer" from
| XPtr on the following very toy example. It has something to do with the
| type of SEXP in the constructor, but I am not very familiar with the Rcpp
| internals to be able to figure it out.
|
| #include <Rcpp.h>
| class World {
| public:
| World() : msg("hello"){}
| World(const std::string s) : msg(s){}
| void set(std::string msg) { this->msg = msg; }
| std::string greet() const { return msg; }
| void addMsg(const World w2) {
| this->msg = this->msg + w2.greet();
| }
| World(SEXP x) {
| Rcpp::XPtr<World> ptr(x);
| msg = ptr->greet();
| }
| private:
| std::string msg;
| };
| RCPP_MODULE(yada){
| using namespace Rcpp ;
| class_<World>( "World" )
| .constructor()
| .constructor<std::string>()
| .method( "greet", &World::greet , "get the message"
| )
| .method( "set", &World::set , "set the
| message" )
| .method( "addMsg", &World::addMsg , "add the
| message from another object" );
| }
|
| And then in R:
|
| >library(yada)
| >a <- new(World,"this is a")
| >b <- new(World,"this is b")
| >a$addMsg(b)
| Error in a$addMsg(b) : expecting an external pointer
|
| I'd appreciate if someone could shed some light on it.
|
| Thanks!
|
| On Wed, Dec 21, 2011 at 7:52 PM, Yasir Suhail <yusuhail at gmail.com> wrote:
|
| Hi,
|
| Other than the approaches mentioned, I can also specialize an as
| <World>(SEXP) as
|
| template <>
| World as<World>(SEXP x) {
| Rcpp::XPtr<World> ptr(x);
| return World(ptr->greet());
| }
|
| However, this also gives segfault at runtime when addMsg is called. The
| final code, with alternative implementations commented out for
| experimentation is:
|
| #include <RcppCommon.h>
| #include <string>
| class World {
| public:
| World() : msg("hello"){}
| World(const std::string s) : msg(s){}
| void set(std::string msg) { this->msg = msg; }
| std::string greet() const { return msg; }
| void addMsg(const World w2) {
| this->msg = this->msg + w2.greet();
| }
| // World(SEXP x);
| /* World(SEXPREC* &w2) {
| msg = ((World*)w2)->greet();
| }
| */
| private:
| std::string msg;
| };
| namespace Rcpp{
|
| template <> SEXP wrap(const World& object);
| template <> World as<World>(SEXP x);
| }
| #include <Rcpp.h>
|
|
| namespace Rcpp {
| template <>
| SEXP wrap( const World& object ){
| Language call( "new", Symbol( "World" ), object.greet() )
| ;
| return call.eval() ;
| }
| template <>
| World as<World>(SEXP x) {
| Rcpp::XPtr<World> ptr(x);
| return World(ptr->greet());
| }
| }
|
|
| /*World::World(SEXP x) {
| Rcpp::XPtr<World> ptr(x);
| msg = ptr->greet();
| }*/
|
| //...
|
| RCPP_MODULE(yada){
| using namespace Rcpp ;
| class_<World>( "World" )
| // expose the default constructor
| .constructor()
| .constructor<std::string>()
| .method( "greet", &World::greet , "get the message" )
| .method( "set", &World::set , "set the message" )
| .method( "addMsg", &World::addMsg , "add the message from another
| object" );
| }
|
| Then, running with R -d gdb
| > a <- new(World,"hello ")
| > b <- new(World,"worlds")
| > a$greet( )
| [1] "hello "
| > a$addMsg( b)
|
| Program received signal EXC_BAD_ACCESS, Could not access memory.
| Reason: KERN_INVALID_ADDRESS at address: 0x0000000011000078
| 0x00000001042032df in std::basic_string<char, std::char_traits<char>,
| std::allocator<char> >::basic_string ()
| (gdb) bt
| #0 0x00000001042032df in std::basic_string<char, std::char_traits
| <char>, std::allocator<char> >::basic_string ()
| #1 0x0000000104358b18 in Rcpp::as<World> ()
| #2 0x000000010435d564 in Rcpp::CppMethod1<World, void,
| World>::operator() ()
| #3 0x000000010435eadb in Rcpp::class_<World>::invoke_void ()
| #4 0x0000000104164670 in CppMethod__invoke_void ()
| #5 0x00000001000928e9 in do_External ()
| #6 0x00000001000c4af7 in Rf_eval ()
| #7 0x00000001000c6d99 in do_begin ()
| #8 0x00000001000c48af in Rf_eval ()
| #9 0x00000001000c7cf3 in Rf_applyClosure ()
| #10 0x00000001000c4778 in Rf_eval ()
| #11 0x00000001000fed75 in Rf_ReplIteration ()
| #12 0x00000001000ff021 in R_ReplConsole ()
| #13 0x00000001000ff590 in run_Rmainloop ()
| #14 0x0000000100000e8b in main ()
| (gdb)
|
| Thanks!
|
| On Wed, Dec 21, 2011 at 7:41 PM, Darren Cook <darren at dcook.org> wrote:
|
| Hello Yasir,
| Could you post your complete (minimal) code to the list. Then
| someone
| might be curious enough to try reproducing the problem.
|
| Darren
|
|
| On 2011-12-22 08:29, Yasir Suhail wrote:
| > Thanks Darren, Douglas, Richard, and Dirk!
| >
| > I can compile with the following definitions:
| >
| > World(SEXP x) {
| > Rcpp::XPtr<World> ptr(x);
| > msg = ptr->msg;
| > }
|
| > ...
|
|
| --
| Darren Cook, Software Researcher/Developer
|
| http://dcook.org/work/ (About me and my work)
| http://dcook.org/blogs.html (My blogs and articles)
|
|
|
|
|
|
|
| ----------------------------------------------------------------------
| _______________________________________________
| 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
--
"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