S7 provides a stable native API for retrieving class definitions and reading properties.
Details
SEXP S7_get_class(SEXP object)returns the stored S7 class definition, orR_NilValueif there is none. UnlikeS7_class(), it does not construct class specifications for base, S3, or S4 objects.SEXP S7_get_prop(SEXP object, SEXP name)reads a property, including custom getters, asprop()does.namemust be a character vector of length one containing a non-missing string.
C and C++
Add S7 to Imports and LinkingTo in DESCRIPTION. In NAMESPACE, add
importFrom(S7, S7_class) and useDynLib(mypkg, .registration = TRUE).
In src/init.c, initialize the API and register the .Call routine:
#include <S7-init.h>
extern SEXP object_value(SEXP object);
static const R_CallMethodDef CallEntries[] = {
{"object_value", (DL_FUNC) &object_value, 1},
{NULL, NULL, 0}
};
void R_init_mypkg(DllInfo *dll) {
S7_init_api();
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
R_forceSymbols(dll, TRUE);
}In src/value.c, define the routine that reads the value property:
#include <S7.h>
SEXP object_value(SEXP object) {
SEXP name = PROTECT(Rf_mkString("value"));
SEXP value = S7_get_prop(object, name);
UNPROTECT(1);
return value;
}An R wrapper in the package can call .Call(object_value, object).
Other C/C++ source files include <S7.h>. In C++ files, use extern "C"
for the declaration and definition of object_value() and the definition
of R_init_mypkg().