Re: [Rcpp-devel] Creating an R interface to non-copyable C++ class
The XPtr is effectively a shared_ptr with special R friendly behavior. Using XPtr is as simple as just passing a pointer to your dynamically allocated C++ object to the XPtr constructor, see https://stackoverflow.com/questions/45947880/pass-a-c-object-as-a-pointer-an-reuse-in-another-function-in-rcpp One huge benefit of using XPtr is that it has built in protection against NULL references (as any time your object is serialized/deserialized it will become invalid). It's also the case that environments like RStudio do special handling for XPtr (i.e. being sure not to suspend RStudio Server sessions that have a live XPtr). On Thu, Apr 12, 2018 at 2:15 PM, Cris Luengowrote: > Hi Dirk, > > I found a more generic solution than a singleton class. I'm extracting > the pointer out of the `std::unique_ptr` using `release`, and putting it > into a `std::shared_ptr`. This one can easily be wrapped using the > standard Rcpp mechanisms. > > This is maybe not the best way to do it, I also followed your > recommendation to look into `Rcpp::XPtr`, and it seems that it > should be possible to pass it a raw pointer and construct a > SEXP around it. But that's more code to write, I like the simple > solutions... > > Many thanks for your help! > Cris. > > > > > On 12 April 2018 at 05:42, Dirk Eddelbuettel wrote: > >> >> On 11 April 2018 at 23:54, Cris Luengo wrote: >> | > The way R thinks about this is that _it_ owns everything, and Rcpp >> makes >> | > getting things back and forth _using the R memory system and its >> lifetime / >> | > reference count control_ fairly easy. >> | >> | Yes, that makes sense. But somehow it is not easy to transfer ownership >> | of an object to R. There needs to be a new object created that it can >> own? >> >> Yes, in general that works just fine. Ie when we do >> >>Rcpp::NumericVector x(10); >> >> we use the R malloc functions, and to R this _is_ the same as a REAL with >> 10 >> elements. Because everything has to be a SEXP, our C++ objects are really >> proxies to underlying SEXPs. And R is happy. And controls everything and >> it >> all works as if you used the C API of R. Which we extend (by a lot, you >> could say) to make things easier. >> >> A unique_ptr with _control on the C++ side_ does not fit that mold at all >> so >> we have to do something different here. The singleton / static instance >> is >> one approach _so that it survives across multiple (different) calls_ from >> R. >> >> I am sure there are other approaches, but they still have to match the >> basic >> constraint of 'SEXP in, SEXP out'. >> >> Hth, Dirk >> >> -- >> http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org >> > > > ___ > Rcpp-devel mailing list > Rcpp-devel@lists.r-forge.r-project.org > https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel > ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] Creating an R interface to non-copyable C++ class
Hi Dirk, I found a more generic solution than a singleton class. I'm extracting the pointer out of the `std::unique_ptr` using `release`, and putting it into a `std::shared_ptr`. This one can easily be wrapped using the standard Rcpp mechanisms. This is maybe not the best way to do it, I also followed your recommendation to look into `Rcpp::XPtr`, and it seems that it should be possible to pass it a raw pointer and construct a SEXP around it. But that's more code to write, I like the simple solutions... Many thanks for your help! Cris. On 12 April 2018 at 05:42, Dirk Eddelbuettelwrote: > > On 11 April 2018 at 23:54, Cris Luengo wrote: > | > The way R thinks about this is that _it_ owns everything, and Rcpp > makes > | > getting things back and forth _using the R memory system and its > lifetime / > | > reference count control_ fairly easy. > | > | Yes, that makes sense. But somehow it is not easy to transfer ownership > | of an object to R. There needs to be a new object created that it can > own? > > Yes, in general that works just fine. Ie when we do > >Rcpp::NumericVector x(10); > > we use the R malloc functions, and to R this _is_ the same as a REAL with > 10 > elements. Because everything has to be a SEXP, our C++ objects are really > proxies to underlying SEXPs. And R is happy. And controls everything and it > all works as if you used the C API of R. Which we extend (by a lot, you > could say) to make things easier. > > A unique_ptr with _control on the C++ side_ does not fit that mold at all > so > we have to do something different here. The singleton / static instance is > one approach _so that it survives across multiple (different) calls_ from > R. > > I am sure there are other approaches, but they still have to match the > basic > constraint of 'SEXP in, SEXP out'. > > Hth, Dirk > > -- > http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org > ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] Creating an R interface to non-copyable C++ class
On 11 April 2018 at 23:54, Cris Luengo wrote: | > The way R thinks about this is that _it_ owns everything, and Rcpp makes | > getting things back and forth _using the R memory system and its lifetime / | > reference count control_ fairly easy. | | Yes, that makes sense. But somehow it is not easy to transfer ownership | of an object to R. There needs to be a new object created that it can own? Yes, in general that works just fine. Ie when we do Rcpp::NumericVector x(10); we use the R malloc functions, and to R this _is_ the same as a REAL with 10 elements. Because everything has to be a SEXP, our C++ objects are really proxies to underlying SEXPs. And R is happy. And controls everything and it all works as if you used the C API of R. Which we extend (by a lot, you could say) to make things easier. A unique_ptr with _control on the C++ side_ does not fit that mold at all so we have to do something different here. The singleton / static instance is one approach _so that it survives across multiple (different) calls_ from R. I am sure there are other approaches, but they still have to match the basic constraint of 'SEXP in, SEXP out'. Hth, Dirk -- http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] Creating an R interface to non-copyable C++ class
> On Apr 11, 2018, at 19:14, Dirk Eddelbuettelwrote: > > On 11 April 2018 at 17:19, Cris Luengo wrote: > | Ideally, an R variable would hold on to this pointer (with or without the > | `std::unique_ptr` around it), and delete the object when it is cleared (or > | garbage collected, or whatever R uses). Is this possible? > > Yes. I have done things like that with eg interfaces to DB engines and alike. > > One approach is to create a singleton class, and have it shield the > std::. You can add an init() function that sets things up, > possibly with arguments from R (standard string, int, ... whatever is > needed). And then add worker functions to set, get, change, ... whatever > you need give the pointer. You can add an explicit wind-down too to log, > lock, close, ... whatever you have to do with the resource. A singleton class is equivalent to a static instance. Basically you're suggesting a static `std::unique_ptr` that will own the object when created. The R interface then has functions that create, modify, query and destroy the object pointed to by the static pointer. That could absolutely work in this case, I don't need there to be more than one object of this class at the time. And it seems a simple approach. I will give this a try in the morning. > The way R thinks about this is that _it_ owns everything, and Rcpp makes > getting things back and forth _using the R memory system and its lifetime / > reference count control_ fairly easy. Yes, that makes sense. But somehow it is not easy to transfer ownership of an object to R. There needs to be a new object created that it can own? Many thanks! Cris. ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] Creating an R interface to non-copyable C++ class
Hi Chris, Thanks for bringing this over here from StackOverflow. On 11 April 2018 at 17:19, Cris Luengo wrote: | I have some functionality in C++ that I need to access from R. My | impression was that Rcpp was the simplest way to accomplish this, but I | haven't been able to make it work yet. | | The core problem, I think, is that data created is not copyable. One of | these functions returns a `std::unique_ptr` owning the pointer to the | object. Other functions take a reference to the object and modify it or | query it. | | Here is what I've tried so far: https://stackoverflow.com/q/49785379/7328782 | | Ideally, an R variable would hold on to this pointer (with or without the | `std::unique_ptr` around it), and delete the object when it is cleared (or | garbage collected, or whatever R uses). Is this possible? Yes. I have done things like that with eg interfaces to DB engines and alike. One approach is to create a singleton class, and have it shield the std::. You can add an init() function that sets things up, possibly with arguments from R (standard string, int, ... whatever is needed). And then add worker functions to set, get, change, ... whatever you need give the pointer. You can add an explicit wind-down too to log, lock, close, ... whatever you have to do with the resource. | The Rcpp-extending vignette says "The macro RCPP_EXPORT_WRAP provides an | easy way to expose a C++ class to R as an external pointer", but looking at | the code it seems to allocate a new object, using `new` and the copy | constructor, and wrap that. Would it be possible to modify the code | generated by this macro to not `new`, but directly use a given pointer? | Would that still allow for lifetime management? Could it be that we are looking at lifetime from opposite sides? The way R thinks about this is that _it_ owns everything, and Rcpp makes getting things back and forth _using the R memory system and its lifetime / reference count control_ fairly easy. It looks like you want to create something that last longer than a single call from R -- and you can, and one way is to provide something outside of R to manage it. Does that make sense? Dirk -- http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel