Search code examples
crrcppr-s4

Use .Call() to send an s4 object to a C struct


I would like to pass a simple s4 object into C and turn it into an simple struct. I'm picturing R code like

setClass("MyClass", slots = list(x = "numeric", y = "integer"))
r_instance = new("MyClass", x = rnorm(5), y = as.integer(1:10))
dyn.load("parse.so")
.Call("parse", r_instance)

with parse.c

#include <R.h>
#include <Rinternals.h>
#include <Rmath.h>

typedef struct {
  double x;
  int y;
} MyStruct;

SEXP parse(SEXP r_instance){
  MyStruct c_instance = MAKE_S4_INTO_STRUCT(r_instance);
  printf("%g %d\n", c_instance->x[0], c_instance->y[0]);
  return R_NilValue;
}

Is there a MAKE_S4_INTO_STRUCT function that would make this work? I haven't found an answer in Hadley's C interface page or the R extensions manual.


Solution

  • Sadly, the "I wish there was a pony" approach does not always work.

    But by creating as<>() and wrap() converters from Rcpp you could build yourself such a facility. See the existing S4 converters examples here or here for inspiration.

    In a nutshell, your struct does not yet exist as either an R type or an Rcpp type, so you will have to provide the mapping. Once you do, things should get peachy as the converters you add will get called "on demand".

    That said, writing such converters is probably not what you should do on your first day with Rcpp ...