A slightly hackish, if effective, workaround I've used in this instance
is to have "as<>()" convert a string argument to a class return value,
thereby avoiding the metaphysics of creating a c++ class in R.
template <> fusionProject::TCFAFunctor *as( SEXP rs ) {
using fusionProject::TCFAFunctor;
if (!Rf_isString( rs ))
throw std::runtime_error("Invalid argument. String
expected!");
std::string defName = as<std::string>( rs );
TCFAFunctor *retptr;
if (defName.compare("A")==0)
retptr = new fusionProject::tcfaDefinitionA;
// else if (defName.compare("B")==0)
// retptr = new fusionProject::tcfaDefinitionB;
else if (defName.compare("C")==0)
retptr = new fusionProject::tcfaDefinitionC;
else
throw std::runtime_error("Unrecognized TCFA definition
label.");
return retptr;
}
This works, with the caveat that the c++ code receiving the return value
is responsible for deleting the pointer. Nonetheless, the syntax feels
suitably "R-ish" on the R side, and I get what I wanted on the c++ side.
--rd
On 12/21/2011 03:55 PM, Yasir Suhail wrote:
Hi
I looked up the previous thread "Creating pointers to objects and
wrapping them"from
http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-April/002170.html,
and it seems that providing a specialization of the wrap<>() function
can help us return classes. Perhaps similarly, one could provide a
specialization of the as<>() function for arguments? While wrap is
implemented with the Language("new" ... function, is there any example
of an as<>() specialization for custom classes? The vignette
(http://dirk.eddelbuettel.com/code/rcpp/Rcpp-extending.pdf) shows a
declaration for as, but no definitions.
Thanks!
Yasir
On Wed, Dec 21, 2011 at 5:45 AM, <rom...@r-enthusiasts.com
<mailto:rom...@r-enthusiasts.com>> wrote:
Iirc, this is not implemented yet.
There is a chance we might add this feature in the future.
Cheers,
Romain
Le 21 déc. 2011 à 10:59, Yasir Suhail <yusuh...@gmail.com
<mailto:yusuh...@gmail.com>> a écrit :
I need to pass a class as an argument in a function I am exposing
to R. From the skeleton package module, let us say that I have
class World {
public:
World() : msg("hello"){}
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
void addMsg(World& w2) {
msg = msg + w2.msg;
}
private:
std::string msg;
};
However, this gives errors of the sort
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/module/Module_generated_CppMethod.h:186:4:
error: invalid initialization of non-const reference of type
'World&' from an rvalue of type 'World'
In file included from
/usr/local/lib/R/site-library/Rcpp/include/RcppCommon.h:306:0,
from
/usr/local/lib/R/site-library/Rcpp/include/Rcpp.h:27,
from rcpp_module.cpp:1:
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/traits/Exporter.h: In
constructor 'Rcpp::traits::Exporter<T>::Exporter(SEXPREC*) [with
T = World, SEXPREC* = SEXPREC*]':
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/as.h:51:51:
instantiated from 'T Rcpp::internal::as(SEXPREC*,
Rcpp::traits::r_type_generic_tag) [with T = World, SEXPREC* =
SEXPREC*]'
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/as.h:75:89:
instantiated from 'T Rcpp::as(SEXPREC*) [with T = World, SEXPREC*
= SEXPREC*]'
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/module/Module_generated_CppMethod.h:186:4:
instantiated from 'SEXPREC* Rcpp::CppMethod1<Class, void,
U0>::operator()(Class*, SEXPREC**) [with Class = World, U0 =
World&, SEXPREC* = SEXPREC*]'
rcpp_module.cpp:86:1: instantiated from here
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/traits/Exporter.h:31:37:
error: no matching function for call to 'World::World(SEXPREC*&)'
rcpp_module.cpp:30:5: note: candidates are: World::World()
rcpp_module.cpp:28:13: note: World::World(const
World&)
make: *** [rcpp_module.o] Error 1
Looking at
http://dirk.eddelbuettel.com/code/rcpp/Rcpp-extending.pdf, it
seems that I can extend Rcpp::as to account for my classes, but I
still have two questions:
1. How do I define the constructor World(SEXP)? Is there a
working example somewhere for a user defined C++ class?
2. Can I also use pointers and pass-by-reference as these are
more often used in real C++ code.
In short, I'd appreciate a way to pass my C++ classes (as the
class and also by ref. or pointer) that have been exposed to R as
arguments to exposed functions. How do I achieve that?
Thanks!
_______________________________________________
Rcpp-devel mailing list
Rcpp-devel@lists.r-forge.r-project.org
<mailto:Rcpp-devel@lists.r-forge.r-project.org>
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
_______________________________________________
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
_______________________________________________
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