[Rcpp-devel] correct way of making custom as and wrap functions available to other packages

Simon Barthelmé simon.barthelme at gipsa-lab.fr
Tue Jul 28 10:59:58 CEST 2015


Dear list,

As a follow-up to last week's discussion, the simplest solution is 
indeed inlining.
You can define your wrapper functions in a header, myPackage.h, 
containing inline function definitions rather than declarations:

----

namespace Rcpp {
template <> inline myClass as(SEXP foo){
     //
}
template <> inline SEXP wrap(myClass &bar){
     //
}

----

You put the header in inst/include, and add -I../inst/include to 
PKG_CPPFLAGS.

Your wrapper functions are now available to other packages via a 
Depends: statement in DESCRIPTION, and you can define a plugin as well 
by adding a file to R/ containing:

inlineCxxPlugin <- Rcpp:::Rcpp.plugin.maker(
     include.before = "#include <myPackage.h>",
     package        = "myPackage"
)

The mistake I was making was to write inline template <> instead of 
template <> inline, which the compiler ignores (rather than issue a 
syntax error). Thanks everybody for your input!

Best

Simon


Le 17/07/2015 20:23, Dirk Eddelbuettel a écrit :
> On 17 July 2015 at 17:41, Simon Barthelmé wrote:
> | Thanks Dirk! I'm not sure how to ensure that only one compilation unit
> | includes the file (the package would have to get rid of RcppExports.cpp
> | somehow, or stuff everything in there). I'm also not sure I understand
> | what you mean by enforcing purity but I'll investigate. The third
>
> Kevin hit that as well:  inline function, and/or templates.  You essentially
> need to avoid having the symbol be created several times over as that gets
> the linker error.
>
> Dirk
>
>
> | solution is the same one Kevin suggested, I think, and I haven't managed
> | to get it to work.
> |
> | Best
> |
> | Simon
> |
> | Le 17/07/2015 17:09, Dirk Eddelbuettel a écrit :
> | > On 17 July 2015 at 16:32, Simon Barthelmé wrote:
> | > | Dear list,
> | > |
> | > | For a package I'm developing (https://github.com/dahtah/imager/) I had
> | > | to write custom "as" and "wrap" functions for third-party classes. I'd
> | > | like to make these wrappers accessible to other developers via inline
> | > | C++ as well as LinkingTo directives (so that they can be used in other
> | > | packages).
> | > | So far I've only managed the former: I have a header file in
> | > | inst/include, called "wrappers.h", that contains the full
> | > | implementations of my custom as and wrap functions. I've written a
> | > | custom inline plugin and everything works fine. However, LinkingTo
> | > | doesn't work: wrappers.h gets included in multiple object files and I
> | > | get linking errors (the linker complains about multiple declarations of
> | > | "as" and "wrap").
> | > | I understand RcppArmadillo manages to get around the problem but I can't
> | > | figure out how. What's the correct way of doing this? Is there a way of
> | > | making as and wrap inline functions so that it's safe to have
> | > | header-only implementations?
> | >
> | > Am at work now with my wrapped in another issue but I think one way of fixing
> | > this is to ensure that only one compilation unit includes the file. Another
> | > is to make sure the header file is "pure" in the 'just templates' sense so
> | > that you do not get multiple instantiations.  A third is to use #define
> | > statements to separate declarations (used for other packages) from definitions
> | > and instantiations (which your package uses).
> | >
> | > I definitely had this design issue and managed to address it.  With a bit
> | > more coffee I may even remember which package that was in...
> | >
> | > Dirk
> | >
> |
>



More information about the Rcpp-devel mailing list