从Rcpp中的包装方法返回自定义对象
returning a custom object from a wrapped method in 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.中的方法中获得了一个外部指针对象
有没有可能从第二类的方法中获得一个正确包装的对象?
谢谢,Thomas
[编辑]
根据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
如果你为它编写一个包装器,这是可能的。这些包装器不是从天而降的,你需要通过提供它来帮助编译器,然后它就会被选中。
RcppBDT的简单示例:
template <> SEXP wrap(const boost::gregorian::date &d) {
// convert to y/m/d struct
boost::gregorian::date::ymd_type ymd = d.year_month_day();
return Rcpp::wrap(Rcpp::Date( ymd.year, ymd.month, ymd.day ));
}
在这里,Boost中的一个类被转换为Rcpp类(Date),然后返回(即使在那里,我们也需要显式包装)。对于更复杂的类,您需要更复杂的转换器。
编辑:当然,您需要记住,从R调用的任何东西仍然需要符合.Call()
规定的基本SEXP foo(SEXP a, SEXP b, ...)
接口。
好吧,我想我明白了。但没有保证。根据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 );
}
如果一个方法期望一个对象作为参数(这里是指向该对象的指针),那么下面的"as"包装器可能很有用:
template <> A* as( SEXP obj){
Rcpp::Environment e(obj);
Rcpp::XPtr<A> xp( (SEXP) e.get(".pointer") );
return (A*) xp;
}
当然,您也可以返回*xp,它允许将非指针作为参数,但这会再次复制对象。
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 通过 NIF 从C++返回自定义数据结构
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 如何在C++中返回自定义类中的分段错误?
- 如何在C++中允许成员函数的自定义返回类型进行类型擦除?
- 如何从 cpp 中的函数返回自定义类对象?
- 从 QAbstractItemModel 返回自定义用户类型
- 如何从类中返回自定义数组项目并操纵其属性?C
- 函数返回自定义的托管类类型
- 从QT C 返回自定义对象,并在QML中打印属性
- 通过 itemAt() 或 collidingItems() 返回自定义 QGraphicsItem
- accept上的QDialog返回自定义类对象
- 从Rcpp中的包装方法返回自定义对象
- c++从函数返回自定义类
- itemAt不返回自定义qGraphicsItem
- Q_INVOKABLE方法返回自定义c++类型
- 是否可以从对话框的 DoModal 函数返回自定义值?
- C++类 - 如何从函数返回自定义类型的向量
- 通过COM返回自定义接口类型的SAFEARRAY到VB6