I suppose that I will share my solution to this issue. I have two utility functions:
using namespace Rcpp; template<class T> XPtr<T> unwrap_robject(const SEXP& sexp){ RObject ro(sexp); if(ro.isObject()){ Language call("as.environment",sexp); SEXP ev = call.eval(); Language call1("get",".pointer",-1,ev); SEXP ev1 = call1.eval(); XPtr<T > xp(ev1); return xp; }else{ XPtr<T > xp(sexp); return xp; } } template<class T> SEXP wrap_in_reference_class(const T& obj,std::string class_name){ XPtr< T > xp(new T(obj)); Language call( "new", Symbol( class_name ),xp); return call.eval(); } And then for object I define something like class MyObject{ public: MyObject(SEXP sexp){ XPtr<MyObject> xp = unwrap_object<MyObject>(sexp); /* copy members from xp here */ } operator SEXP() const{ return wrap_in_reference_class(*this,"MyObject"); } }; and create the module class: RCPP_MODULE(MyModule){ class_<MyObject>("MyObject") .constructor<SEXP>(); } MyObject can now be passed up and down transparently from c++ to R. I am interested to hear feedback as to whether this is a good strategy or not. Ian On Dec 23, 2011, at 3:16 PM, rcpp-devel-requ...@r-forge.wu-wien.ac.at wrote: Send Rcpp-devel mailing list submissions to rcpp-devel@lists.r-forge.r-project.org To subscribe or unsubscribe via the World Wide Web, visit https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel or, via email, send a message with subject or body 'help' to rcpp-devel-requ...@lists.r-forge.r-project.org You can reach the person managing the list at rcpp-devel-ow...@lists.r-forge.r-project.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Rcpp-devel digest..." Today's Topics: 1. g++-llvm still doesn't like RcppArmadillo? (Davor Cubranic) 2. Re: c++ class as argument in rcpp function (using modules) (Yasir Suhail) ---------------------------------------------------------------------- Message: 1 Date: Fri, 23 Dec 2011 11:03:30 -0800 (PST) From: Davor Cubranic <cubra...@stat.ubc.ca> Subject: [Rcpp-devel] g++-llvm still doesn't like RcppArmadillo? To: rcpp-de...@r-forge.wu-wien.ac.at Message-ID: <pine.gso.4.64.1112230955150.8...@be.stat.ubc.ca> Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Did we ever find a way to make RcppArmadillo compile with g++-llvm on OS X Lion? There was a thread in July about unresolved 'arma_version' symbol (http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-July/002621.html), and it appears the only way around it was by compiling with the vanilla g++. I just ran into the same error, using R installed from MacPorts as the R-framework port. This uses the llvm-g++-4.2 toolchain, so getting it to use apple-g++ to compile just RcppArmadillo would probably require manual fiddling with the configure step, which I would prefer to avoid given that this is on a compute cluster where we're automating software installation and upgrading. Also, does anyone know if this will mean that every package that depends on RcppArmadillo will have to avoid using LLVM as well? Installation output below: * installing *source* package 'RcppArmadillo' ... ** package 'RcppArmadillo' successfully unpacked and MD5 sums checked ** libs *** arch - x86_64 /opt/local/bin/llvm-g++-4.2 -I/opt/local/Library/Frameworks/R.framework/Resources/include -I/opt/local/Library/Frameworks/R.framework/Resources/include/x86_64 -I/opt/local/include -I"/opt/local/Library/Frameworks/R.framework/Versions/2.14/Resources/library/Rcpp/include" -I../inst/include -fPIC -pipe -O2 -m64 -c RcppArmadillo.cpp -o RcppArmadillo.o /opt/local/bin/llvm-g++-4.2 -I/opt/local/Library/Frameworks/R.framework/Resources/include -I/opt/local/Library/Frameworks/R.framework/Resources/include/x86_64 -I/opt/local/include -I"/opt/local/Library/Frameworks/R.framework/Versions/2.14/Resources/library/Rcpp/include" -I../inst/include -fPIC -pipe -O2 -m64 -c fastLm.cpp -o fastLm.o /opt/local/bin/llvm-g++-4.2 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/opt/local/lib -L/opt/local/lib/llvm-gcc42 -lgfortran -o RcppArmadillo.so RcppArmadillo.o fastLm.o /opt/local/Library/Frameworks/R.framework/Versions/2.14/Resources/library/Rcpp/lib/x86_64/libRcpp.a -L/opt/local/Library/Frameworks/R.framework/Resources/lib/x86_64 -lRlapack -L/opt/local/Library/Frameworks/R.framework/Resources/lib/x86_64 -lRblas -F/opt/local/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation installing to /opt/local/Library/Frameworks/R.framework/Versions/2.14/Resources/library/RcppArmadillo/libs/x86_64 ** R ** inst ** preparing package for lazy loading ** help *** installing help indices ** building package indices ... *** tangling vignette sources ... 'RcppArmadillo-unitTests.Rnw' ** testing if installed package can be loaded Error in dyn.load(file, DLLpath = DLLpath, ...) : unable to load shared object '/opt/local/Library/Frameworks/R.framework/Versions/2.14/Resources/library/RcppArmadillo/libs/x86_64/RcppArmadillo.so': dlopen(/opt/local/Library/Frameworks/R.framework/Versions/2.14/Resources/library/RcppArmadillo/libs/x86_64/RcppArmadillo.so, 6): Symbol not found: __ZN4arma12arma_version5majorE Referenced from: /opt/local/Library/Frameworks/R.framework/Versions/2.14/Resources/library/RcppArmadillo/libs/x86_64/RcppArmadillo.so Expected in: flat namespace in /opt/local/Library/Frameworks/R.framework/Versions/2.14/Resources/library/RcppArmadillo/libs/x86_64/RcppArmadillo.so Error: loading failed Execution halted ERROR: loading failed * removing '/opt/local/Library/Frameworks/R.framework/Versions/2.14/Resources/library/RcppArmadillo' The downloaded packages are in '/private/tmp/RtmpXwDIXY/downloaded_packages' Warning message: In install.packages("RcppArmadillo") : installation of package 'RcppArmadillo' had non-zero exit status ------------------------------ Message: 2 Date: Fri, 23 Dec 2011 18:16:36 -0500 From: Yasir Suhail <yusuh...@gmail.com> Subject: Re: [Rcpp-devel] c++ class as argument in rcpp function (using modules) To: rcpp-devel@lists.r-forge.r-project.org Message-ID: <cacvqymajpdevkrhv5fcsolb4orfafmqvu+xapj0otyqkygt...@mail.gmail.com> Content-Type: text/plain; charset="iso-8859-1" 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. 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. Thanks! On Thu, Dec 22, 2011 at 9:18 PM, Yasir Suhail <yusuh...@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 <yusuh...@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 <dar...@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) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20111223/0039ff7e/attachment.htm> ------------------------------ _______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel End of Rcpp-devel Digest, Vol 26, Issue 22 ****************************************** _______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel