[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