[Rcpp-devel] integer arrays as arguments for a module function

Chris DuBois chris.dubois at gmail.com
Sat Aug 13 09:52:01 CEST 2011


I didn't find anything too relevant in the unit tests.  I got a bit stuck,
and asked a question on StackOverflow here:
http://stackoverflow.com/questions/7048888/stdvectorstdstring-to-char-array
.

One answer seemed particularly promising (as shown by the working demo:
http://ideone.com/U6QZ5 ).

However, when I put this code into a module, I get an error:
error: argument of type ‘char* (Foo::)(const std::string&)’ does not match
‘char* (Foo::*)(const std::basic_string<char>&)’

Here's the example I'm working with.  Commenting out the std::transform and
it compiles fine.  Why does it work OK when not in a module, but fails when
in a module?

R code:
inc <- paste(readLines('tests/convertCharExample.txt.cpp'),collapse="\n")
fx <- cxxfunction( signature(), "" , include = inc, plugin = "Rcpp" )
a <- Module( "foo_mod", getDynLib(fx) )
b <- new(a$Foo,1:5)
b$convertExample()

convertCharExample.txt.cpp code:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cstring>

class Foo {
public:
  Foo(IntegerVector tail) {
    this->tail = tail;
  }

  char *convert(const std::string & s)
  {
    char *pc = new char[s.size()+1];
    std::strcpy(pc, s.c_str());
    return pc;
  }

  int convertExample() {
       std::vector<std::string>  vs;
       vs.push_back("std::string");
       vs.push_back("std::vector<std::string>");
       vs.push_back("char*");
       vs.push_back("std::vector<char*>");
       std::vector<char*>  vc;

       std::transform(vs.begin(), vs.end(), std::back_inserter(vc),
convert);

       for ( size_t i = 0 ; i < vc.size() ; i++ )
            std::cout << vc[i] << std::endl;

       for ( size_t i = 0 ; i < vc.size() ; i++ )
            delete [] vc[i];
       return 0;
  }
private:
  IntegerVector tail;
};

RCPP_MODULE(foo_mod){
using namespace Rcpp ;
 class_<Foo>( "Foo" )
          .constructor<IntegerVector>()
          .method( "convertExample", &Foo::convertExample ,"")
 ;
}


On Fri, Aug 12, 2011 at 5:31 PM, Dirk Eddelbuettel <edd at debian.org> wrote:

>
> On 12 August 2011 at 16:59, Chris DuBois wrote:
> | Point taken: STL looks like the way to go in general.
> |
> | In my particular example, however, the arrays get immediately cast to
> another
> | structure foo (somebody else's code).  So I need to cast from
> IntegerVector to
> | int[] before they get cast to foo[].  What you suggested works perfectly
> (and
> | makes sense in hindsight).
> |
> | Is the story identical for char[]?  Where x is a CharacterVector, I
> tried
> |
> | char* a = x.begin();
> |
> | and got
> | error: cannot convert ‘Rcpp::Vector<16>::iterator’ to ‘char*’ in
> | assignment
>
> char can be a pain. It is something C and C++ didn't get quite right by
> lacking a base type for string.  Doing it in plain C (as in *argv[] from
> main()) is a pain but doable.
>
> CharacterVector works as the equivalent of std::vector< std::string >. Out
> of
> each element (ie string) you can extract the underlying char* but you may
> have to rely on strcmp etc.  Remember that you may be dealing with pointers
> of pointers...
>
> Have a peek at the unitTests/ directory to see if you find something.
>
> Hope this helps,  Dirk
>
> | Any help much appreciated.
> | Chris
> |
> | On Fri, Aug 12, 2011 at 3:19 PM, Dirk Eddelbuettel <edd at debian.org>
> wrote:
> |
> |
> |     On 12 August 2011 at 14:50, Chris DuBois wrote:
> |     | Hi all,
> |     |
> |     | I'm trying to figure out how to pass in an array of integers to a
> |     function
> |     | inside a module.  For example, adding the following function to
> |     runit.Module.R
> |     | works fine:
> |     |
> |     |         int bla3( IntegerVector x ) {
> |     |               return sum(x);
> |     |         }
> |     |
> |     | However, I need to pass an int array, rather than an IntegerVector.
> |      Using int
> |     | x[] in the arguments doesn't compile (though I'm unfamiliar with
> C++ in
> |     | general, so maybe this shouldn't work anyway).
> |     |
> |     | Alternatively, should I just cast x from an IntegerVector to an int
> |     array?  I
> |     | tried various permutations of as, vector, <int>, etc, and would
> like to
> |     learn
> |     | the proper way of doing this.
> |
> |     You generally do not want old school x[] arrays in C++. Why?  Because
> STL
> |     vectors do _everything_ they do at (essentially) zero added cost,
> free you
> |     from malloc/free and still allow you to access the straight memory
> should
> |     you
> |     need to (to talk to a C API, say).
> |
> |     So use IntegerVector for _the interface_. You can the, if you must,
> do
> |
> |         IntegerVector x;
> |
> |         int a1[] = x.begin();     // STL-style iterator to beginning of
> |     memory
> |         int *a2  = x.begin();     // idem
> |
> |     Hope this helps,  Dirk
> |
> |     --
> |     Two new Rcpp master classes for R and C++ integration scheduled for
> |     New York (Sep 24) and San Francisco (Oct 8), more details are at
> |     http://dirk.eddelbuettel.com/blog/2011/08/04#
> |     rcpp_classes_2011-09_and_2011-10
> |     http://www.revolutionanalytics.com/products/training/public/
> |     rcpp-master-class.php
> |
> |
>
> --
> Two new Rcpp master classes for R and C++ integration scheduled for
> New York (Sep 24) and San Francisco (Oct 8), more details are at
>
> http://dirk.eddelbuettel.com/blog/2011/08/04#rcpp_classes_2011-09_and_2011-10
>
> http://www.revolutionanalytics.com/products/training/public/rcpp-master-class.php
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20110813/73ce0698/attachment.htm>


More information about the Rcpp-devel mailing list