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

Dirk Eddelbuettel edd at debian.org
Sat Aug 13 14:07:21 CEST 2011


On 13 August 2011 at 00:52, Chris DuBois wrote:
| 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 ).

Nice.
 
| 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>&)’

That is an odd issue with string. Not sure I've seen that before.
 
| 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?

I do not know -- maybe Romain has an idea?

What I would do is to forgo std::transform and just do what the convert
function does inside of a little worker loop. Which should compile.

That said, we probably shouldn't have the error you triggered.
 
Dirk

| 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
| 
| 

-- 
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


More information about the Rcpp-devel mailing list