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

Finlay Scott drfinlayscott at gmail.com
Thu Apr 25 10:47:11 CEST 2013


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
>>
>>
>>
>>
>>
>> _______________________________________________
>> Rcpp-devel mailing list
>> Rcpp-devel at lists.r-forge.r-project.org
>> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130425/d466df44/attachment-0001.html>


More information about the Rcpp-devel mailing list