Skip to content

Instantly share code, notes, and snippets.

@Athospd
Last active May 10, 2023 20:47
Show Gist options
  • Save Athospd/90a27d7f987aa888a7c6ea5205cbcd6b to your computer and use it in GitHub Desktop.
Save Athospd/90a27d7f987aa888a7c6ea5205cbcd6b to your computer and use it in GitHub Desktop.
#include <Rcpp.h>
#include <memory>
using namespace Rcpp;
// A simple class for testing ----------------------------
class A{
public:
int value;
A(int x);
};
A::A(int x) {this->value = x + 10;}
using APtr = std::shared_ptr<A>;
class AWrapper{
public:
APtr a_wrap;
AWrapper(int x): a_wrap(new A(x)){};
};
// The regular way to access an instance of a class using XPtr ----------------------------
// Everything is fine here, nothing to do.
// [[Rcpp::export]]
XPtr<A> A_constructor(int x) {
A *a = new A(x);
XPtr<A> out(a, true);
return out;
}
// [[Rcpp::export]]
int A_test(XPtr<A> x) {
return x->value;
}
// THE PROBLEM ----------------------------
// A given C++ lib expect to receive an shared_ptr instead of a class instance itself.
// [[Rcpp::export]]
XPtr<APtr> APtr_constructor(int x) {
APtr a = std::make_shared<A>(x);
std::cout << a->value << std::endl;
XPtr<APtr> out_ptr(&a, true); // <--------------- how do I wrap 'a' here??
return out_ptr;
}
// [[Rcpp::export]]
int APtr_test(XPtr<APtr> x) {
return x->get()->value; // <--------------- how do I access the A instance pointed by APtr x (which was wrapped by XPtr)?
}
// Wrapper solution ----------------------------
// Using an auxiliary class to store a APtr and the XPtr an instance of it.
// [[Rcpp::export]]
XPtr<AWrapper> AWrapper_constructor(int x) {
AWrapper *a_w = new AWrapper(x);
XPtr<AWrapper> out_ptr(a_w, true);
return out_ptr;
}
// [[Rcpp::export]]
int AWrapper_test(XPtr<AWrapper> x) {
return x->a_wrap->value;
}
/*** R
# Working correctly ------------------------------------
a <- A_constructor(42)
A_test(a)
# > [1] 52
# NOT working ------------------------------------------
a_ptr <- APtr_constructor(42)
APtr_test(a_ptr)
# > [1] -1652502752 # garbage, might vary
# working ------------------------------------------
a_w <- AWrapper_constructor(42)
AWrapper_test(a_w)
# > [1] 52
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment