Розглянемо 1) спеціальний клас з потенційно великим друком пам’яті та 2) функцію верхнього рівня, яка виконує деяку попередню обробку, потім створює та повертає новий об’єкт нашого спеціального класу. Щоб уникнути зайвого копіювання за значенням, функція розподіляє об'єкт і повертає на нього вказівник.
Виходячи з попередньої дискусії , здається, що правильний спосіб повернути вказівник на новостворений об’єкт - це обернути його Rcpp::XPtr<>
. Однак R потім розглядає це ефективно як externalptr
, і я намагаюся знайти належний спосіб викласти це за допомогою сучасного RCPP_EXPOSED_CLASS
і RCPP_MODULE
способу здійснення справ.
Альтернатива - повернути необроблений покажчик. Але тоді я не на 100% впевнений у тому, що пам'ять об'єкта правильно очищається. Я побіг valgrind
перевірити на предмет витоку пам’яті, і його не знайшли. Однак хто займається прибиранням? R?
test.cpp
#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")
;
}
В Р
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 ... Може, за допомогою вмотивованого пошуку ви зможете знайти щось досить близьке?