[Rcpp-devel] Question about custom as and wrap functions
JJ Allaire
jj.allaire at gmail.com
Thu Apr 25 12:13:30 CEST 2013
Finlay,
Are you running Rcpp 0.10.3 (that version is required for the behavior I
mentioned to work).
If you could provide a fully self-contained reproducible example then it
will be pretty easy for us to track down the source of the troubles
(perhaps create a simple test package then upload it to a gist?)
J.J.
On Thu, Apr 25, 2013 at 4:47 AM, Finlay Scott <drfinlayscott at gmail.com>wrote:
> 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/a6c76dc5/attachment.html>
More information about the Rcpp-devel
mailing list