0

I would like to emulate this example here, but use a method of my own class on an instantiated object. The design choice is that I would like to make a statistical model available in R, having written the core in C++. The oo design is important to that class of problem for memory reasons. In short, it's a likelihood endowed with data and constant parameters, which then gets passed to an optimizer in R.

Because exposing classes in R is tricky when defining cluster environments, I am constructing an object inside this function and wish to return a function pointer to this very object like so:

Typedefs:

typedef std::function<double(int, int) > OrdinaryFunc;
typedef double (*funcPtr)(int a,int b);

And the two functions that collectively should enable a call to a member function:

  //' @export
// [[Rcpp::export]]
Rcpp::XPtr<OrdinaryFunc> ofunc(){

  MatrixAttempt maus(1,2,true,Eigen::MatrixXd::Zero(800,1),false,false);
  //maus.ExtraSetter(1,"Dynamic","Gaussian");
  //maus.GetModelType();

  OrdinaryFunc ofu = std::bind(&MatrixAttempt::tdens,maus,std::placeholders::_1, std::placeholders::_2);

  //return(Rcpp::XPtr<OrdinaryFunc>(new OrdinaryFunc(&ofu)));

  return(Rcpp::XPtr<OrdinaryFunc>(&ofu));

}


//' @export
// [[Rcpp::export]]
double callViaXPtr( int a, int b, SEXP xpsexp) {
  Rcpp::XPtr<funcPtr> xpfun(xpsexp);
  funcPtr fun = *xpfun;
  double y = fun(a,b);
  return (y);
}

My attempt at a solution was to include a function pointer in my class, which strikes me as unnecessarily hacky. The example provided here helped with creating adequate pointers to instantiated class members, so that it compiles fine. Back home in R, I ran

fun <- ofunc() and then callViaXPtr(1,2,fun) which crashed my R session with no error message.

How can I construct an instance of a class inside a wrapper function and return it as a pointer to the R session so that it can be called like a normal function?

Importantly, the function should be exportable to cluster nodes using the parallel package and not suffer from the lack of recognition as the modules output does.

halfer
  • 19,824
  • 17
  • 99
  • 186
Hirek
  • 435
  • 3
  • 12
  • 2
    In a package, use a specially name header file `package_types.h` (and/or one or two variants, see the Attributes vignette) which will then be pulled in by `RcppExports.cpp` making your package types visible and useable. – Dirk Eddelbuettel Aug 14 '21 at 16:09
  • great thank you Dirk! But the code still seems to not work, somehow I get the error: "use of undeclared identifier 'LogLikelihoodLowMem" although that is is very much a declared method in my class. – Hirek Aug 14 '21 at 16:40
  • Look at working packages using XPtr and try to identify what they do differently. The 'cran' org at GitHub (ie https://github.com/cran) allows you to search and XPtr is a weird enough pattern to work in searches. And/or as always, babystep. One class. Don't export the class. Use an empty function to instantiate, one to increase a counter there, one to read the counter as a scalar, one to destroy / deallocate. Create such as existence proof. Only _then_ make it more complicated. – Dirk Eddelbuettel Aug 14 '21 at 16:45
  • Honestly, my sense is that people use R for the handling of data and then use Rcpp-exported functions to speed up for loops etc. I have a working oo c++ programme with a main but wanted to give the user the possibility to use R's optimisers on it, so you can 'play' and control. However, I am considering writing the whole thing, incl. optimisation in c++ and then export to R the very top via a simple wrapper. It's a bit of a shame and XPtr seemed perfect but I was hoping to find or be told about a simple example like the one with a simple function in the gallery, just an oo-version of it? – Hirek Aug 14 '21 at 16:58
  • Also, I can only search for package names or repositories, not the source code. Is there a more advanced search function? – Hirek Aug 14 '21 at 17:07
  • I worked it out using this code here https://stackoverflow.com/questions/5154116/stdfunction-to-member-function and I modified the question a bit but executing the example https://gallery.rcpp.org/articles/passing-cpp-function-pointers/ still crashes my R session without error message, when I call callViaXPtr. – Hirek Aug 14 '21 at 18:32
  • @DirkEddelbuettel I edited the question and included my version of https://gallery.rcpp.org/articles/passing-cpp-function-pointers/ . If the above example can be made to work on your machine, I would love to write this (and my other q's) up as gallery items as there is a real need in the applied stats community to use oo c++ code. I haven't found any examples of this elsewhere unless you had something in mind? – Hirek Aug 14 '21 at 18:42
  • To explain the issue: the reason why R crashes is that your function `ofunc` returns a dangling pointer to memory that no longer exists. – Konrad Rudolph Aug 31 '21 at 22:48
  • So does that mean I should use keyword new to avoid garbage collection? However, where do I delete it then? – Hirek Sep 01 '21 at 23:35

0 Answers0