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

Dirk Eddelbuettel edd at debian.org
Sat Aug 13 19:17:20 CEST 2011


On 13 August 2011 at 07:07, Dirk Eddelbuettel wrote:
| On 13 August 2011 at 00:52, Chris DuBois wrote:
| | 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?

Got it. Gotta "love" C++ error messages. Upon staring at (hand-indented)

file7b8c8784.cpp:49:76: error: argument of type \
  ‘char* (Foo::)(const std::string&)’ does not match \
  ‘char* (Foo::*)(const std::basic_string<char>&)’

for a bit longer, I realized that it is not the 'std::string' vs
'std::basic_string' issue, but rather the 'Foo::' vs 'Foo::*' !

Making convert() a free function is all that it takes:


edd at max:/tmp$ r chris.r 
Loading required package: methods
std::string
std::vector<std::string>
char*
std::vector<char*>
edd at max:/tmp$ 


The file 'chris.r' is included below.  Thanks for posting a self-contained
example -- 'mud-wrestling' these issues one by one is still the best way
forward.

There may be a way to do it with convert() as a member function though...

Dirk


-----------------------------------------------------------------------------
library(inline)

inc <- '
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cstring>

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

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

  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 ,"")
;
}
'


#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()


-----------------------------------------------------------------------------


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