[Rcpp-devel] Question about custom as and wrap functions

Alex Ustian alex.l.ustian at gmail.com
Thu Apr 25 13:22:43 CEST 2013


Hello Finlay,

I believe that I ran into a similar problem a few weeks ago.  Maybe you can
find it on the recent archive of the list.  I was having a similar issue
with RcppExports.cpp not compiling because it couldn't recognize a type.

What ended up working for me was to use the RcppAttributes 'interface'
functionality.  It's described in section 3.5 of the RcppAttributes
vignette.  By adding '// [[Rcpp::interfaces(r, cpp)]]' to one of your .cpp
source files Rcpp will automatically build the header (named after the
package) that JJ was alluding to and then you can manually modify it to
include the other headers that you need.  By deleting the auto-generated
key at the top of the 'asWrapExample.h' header (in your case) Rcpp won't
re-generate it and it is automatically included in RcppExports.cpp, along
with your specialized headers required for your package.

I don't know why just manually creating it yourself like JJ suggested and
what you seem to do didn't work, but maybe going through the package's
auto-generation stuff will.

Hope that helps,

Alex




> Thanks for the reply. I followed your suggestion and changed the name of
> the header file in /inst/include to 'asWrapExample.h' (the name of the
> package). I then changed the #include in the 'DummyClass_example.cpp' file
> to reflect that change. I also added:
>
> PKG_CXXFLAGS=-I../inst/include
>
> To the top of the Makevars file. However, I still get the same error. I
> have the feeling I'm missing something obvious. Thanks for the help so far.
>
> Yours
>
> Finlay
>
>
>
> On Wed, Apr 24, 2013 at 5:41 PM, JJ Allaire <jj.allaire at gmail.com> wrote:
>
> > Hi Finlay,
> >
> > If you name your include file the same name as your package then it will
> > be included automatically in RcppExports.cpp. The convention at work here
> > is that any custom as/wrap handlers should be accumulated (or referenced
> > from) that single file. This mirrors the existing convention used by
> Rcpp,
> > RcppArmadillo, RcppEigen, etc. to have a single global header file for
> > their C++ API.
> >
> > J.J.
> >
> >
> > On Wed, Apr 24, 2013 at 8:22 AM, Finlay Scott <drfinlayscott at gmail.com
> >wrote:
> >
> >> Hi
> >> First of all I want to say how impressed I am with Rcpp. I think it is
> >> going to be very useful for some of the packages I am developing. Thank
> you
> >> very much for developing it.
> >>
> >> I have a question regarding writing custom as and wrap functions for my
> >> own classes. Following the example in:
> >>
> >> http://gallery.rcpp.org/articles/custom-as-and-wrap-example/
> >>
> >> I can get my own minimal example to work with a very simple class, and
> >> using the sourceCpp() function.
> >>
> >> The cpp code saved as a *.cpp file:
> >>
> >>     #include <RcppCommon.h>
> >>
> >>     class DummyClass {
> >>         public:
> >>             double value;
> >>     };
> >>
> >>     namespace Rcpp {
> >>         // non-intrusive extension via template specialisation
> >>         template <> DummyClass as(SEXP dt);
> >>         // non-intrusive extension via template specialisation
> >>         template <> SEXP wrap(const DummyClass &d);
> >>     }
> >>
> >>     #include <Rcpp.h>
> >>
> >>     // define template specialisations for as and wrap
> >>     namespace Rcpp {
> >>         template <> DummyClass as(SEXP dtsexp) {
> >>         S4 dc_s4 = Rcpp::as<S4>(dtsexp);
> >>         DummyClass dc;
> >>         dc.value = dc_s4.slot("value");
> >>         return dc;
> >>         }
> >>
> >>         template <> SEXP wrap(const DummyClass &d) {
> >>         Rcpp::S4 dc_s4("DummyClass");
> >>         dc_s4.slot("value") = d.value;
> >>         return Rcpp::wrap(dc_s4);
> >>         }
> >>     }
> >>
> >>     // [[Rcpp::export]]
> >>     DummyClass test_as_wrap(DummyClass dc, double multiplier){
> >>         DummyClass dc_out;
> >>         dc_out.value = dc.value * multiplier;
> >>         return dc_out;
> >>     }
> >>
> >>
> >> And the following R code compiles and calls the function:
> >>
> >>     library(Rcpp)
> >>     sourceCpp("DummyClass_example.cpp")
> >>     setClass("DummyClass", representation(value = "numeric"))
> >>     dc <- new("DummyClass")
> >>     dc at value <- 23
> >>     test_as_wrap(dc, 4)
> >>
> >> This works just fine (like magic!) and the test_as_wrap() function is
> >> happily called from R and returns an object of type DummyClass. I want
> to
> >> use a similar approach in a package, so I made a minimal package using:
> >>
> >> Rcpp.package.skeleton("asWrapExample",attributes=TRUE)
> >>
> >> I then split my original cpp file above into header and source code
> >> files. In the /inst/include directory I placed a file
> >> 'DummyClass_example.h' which has:
> >>
> >>     #include <RcppCommon.h>
> >>
> >>     class DummyClass {
> >>         public:
> >>             double value;
> >>     };
> >>
> >>     namespace Rcpp {
> >>         // non-intrusive extension via template specialisation
> >>         template <> DummyClass as(SEXP dt);
> >>         // non-intrusive extension via template specialisation
> >>         template <> SEXP wrap(const DummyClass &d);
> >>     }
> >>
> >> In the /src directory I placed a file 'DummyClass_example.cpp' which
> has:
> >>
> >>     #include "../inst/include/DummyClass_example.h"
> >>     #include <Rcpp.h>
> >>
> >>     // define template specialisations for as and wrap
> >>     namespace Rcpp {
> >>         template <> DummyClass as(SEXP dtsexp) {
> >>         S4 dc_s4 = Rcpp::as<S4>(dtsexp);
> >>         DummyClass dc;
> >>         dc.value = dc_s4.slot("value");
> >>         return dc;
> >>         }
> >>
> >>         template <> SEXP wrap(const DummyClass &d) {
> >>         Rcpp::S4 dc_s4("DummyClass");
> >>         dc_s4.slot("value") = d.value;
> >>         return Rcpp::wrap(dc_s4);
> >>         }
> >>     }
> >>
> >>     // [[Rcpp::export]]
> >>     DummyClass test_as_wrap(DummyClass dc, double multiplier){
> >>         DummyClass dc_out;
> >>         dc_out.value = dc.value * multiplier;
> >>         return dc_out;
> >>     }
> >>
> >> When I try to compile the package I get this error message:
> >>
> >>     RcppExports.cpp:9:1: error: 'DummyClass' does not name a type
> >>
> >> This is probably caused by the RcppExports.cpp not having an #include
> for
> >> my DummyClass_example.h.
> >> I understand the RcppExports.cpp file is automatically generated by the
> >> magic of Rcpp so there is no point in adding it there by hand.
> >> I've looked at the documentation but it is not clear to me how I can
> tell
> >> RcppExports to also include my header file (if this is the source of the
> >> problem).
> >> Have I missed something in the documentation, or is there an example I
> >> can follow?
> >> Any help is appreciated.
> >>
> >> Yours
> >>
> >> Finlay
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130425/826a433c/attachment-0001.html>


More information about the Rcpp-devel mailing list