Pertimbangkan 1) kelas khusus dengan cetakan memori yang berpotensi besar, dan 2) fungsi tingkat atas yang melakukan beberapa pra-pemrosesan, kemudian buat dan kembalikan objek baru dari kelas khusus kami. Untuk menghindari penyalinan yang tidak perlu dengan nilai, fungsi mengalokasikan objek dan mengembalikan pointer ke sana.
Berdasarkan diskusi sebelumnya , tampaknya cara yang tepat untuk mengembalikan pointer ke objek yang baru dibuat adalah dengan membungkusnya Rcpp::XPtr<>
. Namun, R kemudian melihatnya secara efektif externalptr
, dan saya berjuang untuk menemukan cara yang tepat untuk melemparkannya dengan cara modern RCPP_EXPOSED_CLASS
dan RCPP_MODULE
melakukan sesuatu.
Alternatifnya adalah mengembalikan pointer mentah. Tapi kemudian saya tidak 100% yakin bahwa memori objek dibersihkan dengan benar. Saya berlari valgrind
untuk menguji kebocoran memori, dan tidak menemukan apa pun. Namun, siapa yang membersihkan? 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")
;
}
Dalam 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
Pertanyaan saya adalah apakah Rcpp::Xptr<>
cara yang tepat untuk mengembalikan pointer, dan jika demikian, bagaimana saya membuat R untuk melihat hasilnya Double
, bukan externalptr
? Atau, jika mengembalikan pointer mentah tidak menyebabkan masalah memori, siapa yang membersihkan objek yang dibuat fungsi?
CustomClass*
. Aplikasi sebenarnya adalah struktur data khusus tanpa R yang setara dan semua interaksi dilakukan melalui fungsionalitas yang diekspos oleh RCPP_MODULE
. Kecocokan terdekat dengan pencarian termotivasi yang saya temukan adalah pos dari 7 tahun yang lalu , di mana sepertinya saya perlu mendefinisikan template <> CustomClass* as()
konverter. Namun, saya tidak jelas bagaimana harus berinteraksi dengan RCPP_MODULE
dan RCPP_EXPOSED_CLASS
, terutama karena saya pikir yang terakhir sudah didefinisikan wrap()
dan as()
.
RCPP_EXPOSED_CLASS
dan RCPP_MODULE
benar-benar cara untuk melakukannya? Saya belum pernah menggunakan atau melihat itu sebelumnya.
Rcpp::XPtr
membuat pointer eksternal dari kode C ++. Dan Anda ingin melakukan itudouble *
atau apa pun muatan Anda. Seharusnya ada contoh di sini, di Galeri, di GitHub ... Mungkin dengan pencarian termotivasi Anda dapat menemukan sesuatu yang cukup dekat?