考虑1)具有潜在的大内存打印的自定义类,以及2)执行一些预处理,然后创建并返回我们的自定义类的新对象的顶级函数。为避免不必要的值复制,该函数分配对象并返回指向它的指针。
根据前面的讨论,似乎将指针返回到新创建的对象的正确方法是将其包装为Rcpp::XPtr<>
。然而,R则认为它有效的externalptr
,而我在努力寻找与现代投它的正确方法RCPP_EXPOSED_CLASS
和RCPP_MODULE
做事的方式。
另一种方法是返回原始指针。但是,我不能100%地确定对象内存是否已正确清理。我跑去valgrind
测试内存泄漏,但没有发现任何泄漏。但是,谁清理呢?R?
测试文件
#include <Rcpp.h>
// Custom class
class Double {
public:
Double( double v ) : value(v) {}
double square() {return value*value;}
private:
double value;
};
// Make the class visible
RCPP_EXPOSED_CLASS(Double)
// Option 1: returning raw pointer
Double* makeDouble( double x ) {
Double* pd = new Double(x);
return pd;
}
// Option 2: returning XPtr<>
SEXP makeDouble2( double x ) {
Double* pd = new Double(x);
Rcpp::XPtr<Double> ptr(pd);
return ptr;
}
RCPP_MODULE(double_cpp) {
using namespace Rcpp;
function( "makeDouble", &makeDouble );
function( "makeDouble2", &makeDouble2 );
class_<Double>("Double")
.constructor<double>("Wraps a double")
.method("square", &Double::square, "square of value")
;
}
在R中
Rcpp::sourceCpp("test.cpp")
d1 <- makeDouble(5.4) # <-- who cleans this up???
# C++ object <0x56257d628e70> of class 'Double' <0x56257c69cf90>
d1$square()
# 29.16
d2 <- makeDouble2(2.3)
# <pointer: 0x56257d3c3cd0>
d2$square()
# Error in d2$square : object of type 'externalptr' is not subsettable
我的问题是Rcpp::Xptr<>
返回指针的方法是否正确,如果是,我如何让R将结果视为Double
,而不是externalptr
?另外,如果返回原始指针不会导致内存问题,谁清理函数创建的对象?
CustomClass*
。真正的应用程序是一个自定义数据结构,没有R等效项,所有交互都通过公开的功能完成RCPP_MODULE
。我最有动机的搜索发现最接近的匹配是7年前的帖子,看来我需要定义一个template <> CustomClass* as()
转换器。但是,我不清楚它应如何与RCPP_MODULE
和交互RCPP_EXPOSED_CLASS
,尤其是因为我认为后者已经定义了wrap()
和as()
。
RCPP_EXPOSED_CLASS
和RCPP_MODULE
真的是这样做的方法吗?我以前从未使用过或看到过。
Rcpp::XPtr
从C ++代码创建一个外部指针。而且您想强制执行它double *
或执行任何有效负载。这里应该有示例,在GitHub的Gallery上...也许通过积极的搜索,您可以找到足够接近的东西?