Rcpp模块存在以下问题: 假设我在Rcpp模块中有两个类
class A { public: int x; }; class B public: A get_an_a(){ A an_a(); an_a.x=3; return an_a; } }; RCPP_MODULE(mod){ using namespace Rcpp ; class_<A>("A") .constructor() .property("x",&A::get_x) ; class_<B>("B) .constructor() .method("get_an_A",&get_an_a) ; }.
现在编译失败,因为它不知道如何处理A的返回类型.
我想我可以用Rcpp :: Xptr做些什么,但是,我无法将其连接到Rcpp为类A生成的S4结构.实际上,我是从R中的方法获得一个外部指针对象. /p>
是否有可能从第二类的方法中获取正确包装的对象?
谢谢, 托马斯
根据Dirk的回答,我构造了一个包装器,可以创建包装的S4对象:
template <> SEXP wrap(const A &obj) { // insprired from "make_new_object" from Rcpp/Module.h Rcpp::XPtr<A> xp( new A(obj), true ) ; // copy and mark as finalizable Function maker=Environment::Rcpp_namespace()[ "cpp_object_maker"]; return maker ( typeid(A).name() , xp ); }仍然,我不知道如何将对象作为方法/函数的参数返回.以下内容不起作用:
template <> A* as( SEXP obj){ Rcpp::List l(obj); Rcpp::XPtr<A> xp( (SEXP) l[".pointer"] ); return (A*) xp; }那么如何从参数列表中SEXP提供的S4对象中获取指向C ++对象的外部指针?
解决方案此功能已在Rcpp 0.10.0中添加
还有其他原因导致您的代码无法编译.下面的代码对我有用:
class A { public: A(int x_) : x(x_){} int x; }; class B { public: A get_an_a(){ A an_a(3); return an_a; } }; RCPP_EXPOSED_CLASS(A) RCPP_EXPOSED_CLASS(B) RCPP_MODULE(stackmod){ using namespace Rcpp ; class_<A>("A") .constructor<int>() .field("x",&A::x) ; class_<B>("B") .constructor() .method("get_an_A",&B::get_an_a) ; }要付出的代价是为所有满足以下条件的类调用宏RCPP_EXPOSED_CLASS:
- 您的一个模块正在曝光
- 您想将其用作公开方法的结果或用作参数
有了这个,我得到:
> b <- new( B ) > b$get_an_A( ) C++ object <0x10330a9d0> of class 'A' <0x1006f46e0> > b$get_an_A( )$x [1] 3I have the following problem with the Rcpp module: let's assume I've two classes in a Rcpp module
class A { public: int x; }; class B public: A get_an_a(){ A an_a(); an_a.x=3; return an_a; } }; RCPP_MODULE(mod){ using namespace Rcpp ; class_<A>("A") .constructor() .property("x",&A::get_x) ; class_<B>("B) .constructor() .method("get_an_A",&get_an_a) ; }.
Right now compilation fails as it does not know what to do with the return type of A.
I figured I could do something with Rcpp::Xptr, however, then I can't connect it to the S4 structure that Rcpp generated for the class A. I actually get an external pointer object from the method in R.
Is there any possiblity to get a correctly wrapped object back from a method of the second class?
Thanks, Thomas
[edit]
According to Dirk's answer I constructed a wrapper that can create the wrapped S4 object:
template <> SEXP wrap(const A &obj) { // insprired from "make_new_object" from Rcpp/Module.h Rcpp::XPtr<A> xp( new A(obj), true ) ; // copy and mark as finalizable Function maker=Environment::Rcpp_namespace()[ "cpp_object_maker"]; return maker ( typeid(A).name() , xp ); }Still, I don't know how to get the object back in as an parameter to a method/function. The following is not working:
template <> A* as( SEXP obj){ Rcpp::List l(obj); Rcpp::XPtr<A> xp( (SEXP) l[".pointer"] ); return (A*) xp; }So how could I get the external pointer to the C++ object from the S4 object provided as SEXP in the parameter list?
解决方案This feature has been added in Rcpp 0.10.0
There were other reasons why your code did not compile. The code below works for me:
class A { public: A(int x_) : x(x_){} int x; }; class B { public: A get_an_a(){ A an_a(3); return an_a; } }; RCPP_EXPOSED_CLASS(A) RCPP_EXPOSED_CLASS(B) RCPP_MODULE(stackmod){ using namespace Rcpp ; class_<A>("A") .constructor<int>() .field("x",&A::x) ; class_<B>("B") .constructor() .method("get_an_A",&B::get_an_a) ; }The price to pay is to call the macro RCPP_EXPOSED_CLASS for all classes that:
- One of your module is exposing
- You want to use as result of an exposed method or as a parameter
With this, I get:
> b <- new( B ) > b$get_an_A( ) C++ object <0x10330a9d0> of class 'A' <0x1006f46e0> > b$get_an_A( )$x [1] 3
更多推荐
从Rcpp中的包装方法返回自定义对象
发布评论