r-lib / R6

Encapsulated object-oriented programming for R
https://R6.r-lib.org
Other
410 stars 56 forks source link

Expose a C struct to R with R6? #219

Closed zoj613 closed 3 years ago

zoj613 commented 3 years ago

I am looking for a way to expose a C struct to R code. I have a C struct like this:

        struct generator {
            void* base;
            uint64_t (*func_pointer)(void* base);
        };

C functions that access this structure take its pointer as an argument, like:

    int some_func(struct generator* gen, int arg2, double arg3);

The goal is to create an extension of this C code that can be ran in R. The problem I have is that I am not sure how to make this struct available to R so that the function some_func can be called repeatedly in R while keeping the same struct intact throughout the program.

In python this struct would just be accessed via a class attribute (with Cython) anytime the C function is called in python.

I am looking to do the same thing in R using R6, but I am not sure how to achieve it. Any suggestions?

gaborcsardi commented 3 years ago

You can call R functions from C, that is not a problem. Instead of a function pointer, an R function is just a SEXP in C. The documentation is here: https://cran.r-project.org/doc/manuals/R-exts.html#Evaluating-R-expressions-from-C

zoj613 commented 3 years ago

You can call R functions from C, that is not a problem. Instead of a function pointer, an R function is just a SEXP in C. The documentation is here: cran.r-project.org/doc/manuals/R-exts.html#Evaluating-R-expressions-from-C

I think you're misinterpreting my question here. I know you can call R functions in C. What I want is to make the struct available in R so I can pass it back into C via R as an argument whenever I want to make a call to some_func via the .Call interface. the generator struct here is an instance that I want associated with a single S3/S4/R6 object and made available to that object for the duration of its life so it can be reused on subsequent calls to some_func.

zoj613 commented 3 years ago

It appears as though an external pointer is what I want, according to http://www.hep.by/gnu/r-patched/r-exts/R-exts_122.html.

It seems like an external pointer is able to allow me to wrap the struct and attach it to an R object as an attribute. then whenever I need to make a call to a C function in R I can pass the external pointer as an argument to the C function an unpack it in C.

zoj613 commented 3 years ago

solved using external pointers. closing.