Thanks Romain for that elegant solution. Best, Gregor
On Wed, 22 Jan 2014 20:23:10 +0100 Romain François <rom...@r-enthusiasts.com> wrote: > Hello, > > The problem is that you have logic in both your mother and child packages. > IMO, you should only have logic in the mother package. > > I’ve done this in a number of packages, it requires a bit of work > initially, but not that much. > > What I’d do is have something like this in mother/inst/include/mother.h : > > #if defined(COMPILING_MOTHER) > // just declare, will be defined in test.c > SEXP fun(SEXP test) ; > #else > inline SEXP fun(SEXP test){ > typedef SEXP(*Fun)(SEXP); > static Fun fun = (Fun)R_GetCCallable("mother", "fun") ; > return fun(test) ; > } > #endif > > In your test.c file, make sure you define COMPILING_MOTHER before you > include mother.h, something like this > > #include <R.h> > #include <Rinternals.h> > #include <R_ext/Rdynload.h> > #define COMPILING_MOTHER > #include <mother.h> > > SEXP fun(SEXP); > > void R_init_mother(DllInfo *dll) { > R_RegisterCCallable("mother", "fun", (DL_FUNC) &fun); > } > > SEXP fun(SEXP test) { > Rprintf("fun so much fun\n"); > return R_NilValue; > } > > So that in your child package you only have to use it, something like: > > #include <Rinternals.h> > #include <R_ext/Rdynload.h> > #include <mother.h> > > SEXP afun(SEXP test) { > fun(test); > return R_NilValue; > } > > Note that if you only want the interface between the two packages to be at > low level (not visible from R), then you don’t need to conform to the > SEXP(SEXP...) interface. You can use anything you like. > > Romain > > Le 22 janv. 2014 à 19:56, Gregor Kastner <gregor.kast...@wu.ac.at> a écrit : > > > Hi again, > > > > On Wed, 22 Jan 2014 06:39:17 -0600 > > Dirk Eddelbuettel <e...@debian.org> wrote: > > > > | Working examples I know of: > > | > > | 'xts' importing two functions from 'zoo' > > | > > | 'RcppXts' importing approx. ten functions from 'xts' > > | > > | Maybe by comparing to these you can sort out the missing step at your > > end. > > > > Thanks Dirk for the hints; I finally got the code running. Important point > > is that R_init_PKGNAME() is declared as extern "C" (or RcppExport, of > > course) if using g++ in both the mother and the child package. > > (Interestingly, dyn.load() only complains when either the mother or the > > child package don't do so, but not if both don't do so => SEGFAULT.) > > Since it took me almost the entire afternoon to figure that out, I'll > > document a working example here. > > > > Scenario: We have a 'mother' package, which wants to make some C/C++ > > routines available to the 'child' package to be called directly from > > C/C++ level. Thus, mother's 'src' cointains: > > > > > > ********* BEGIN test.c ********* > > > > #include <R.h> > > #include <Rinternals.h> > > #include <R_ext/Rdynload.h> > > > > SEXP fun(SEXP); > > > > void R_init_mother(DllInfo *dll) { > > R_RegisterCCallable("mother", "fun", (DL_FUNC) &fun); > > } > > > > SEXP fun(SEXP test) { > > Rprintf("fun so much fun\n"); > > return R_NilValue; > > } > > > > ********** END test.c ********** > > > > > > (Note that no extern "C" is needed here because it will be compiled with > > gcc anyway). > > > > The child uses Rcpp and mother, thus has > > > > > > ********* BEGIN DESCRIPTION ********* > > > > LinkingTo: mother, Rcpp > > Depends: mother, Rcpp > > Imports: mother, Rcpp > > > > ********** END DESCRIPTION ********** > > > > > > in its DESCRIPTION file, and > > > > > > ********* BEGIN test.cpp ********* > > > > #include <Rinternals.h> > > #include <R_ext/Rdynload.h> > > > > extern "C" { > > SEXP afun(SEXP); > > SEXP(*fun)(SEXP); > > > > void R_init_child(DllInfo *info) { > > fun = (SEXP(*)(SEXP)) R_GetCCallable("mother", "fun"); > > } > > > > SEXP afun(SEXP test) { > > fun(test); > > return R_NilValue; > > } > > } > > > > ********** END test.cpp ********** > > > > (Note that extern "C" is crucial here.) After installing mother and > > child, we have: > > > >> library(child) > > Loading required package: mother > > Loading required package: Rcpp > >> .Call("afun", 123, PACKAGE="child") > > fun so much fun > > NULL > >> > > > > Maybe it is of help to someone; please excuse me if I bored anyone with > > trivialities. > > > > Best, > > Gregor > > > > ______________________________________________ > > R-devel@r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel