从Rcpp中的包装方法返回自定义对象 [英] returning a custom object from a wrapped method in Rcpp

查看:89
本文介绍了从Rcpp中的包装方法返回自定义对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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] 3

I 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中的包装方法返回自定义对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆