[Rcpp-devel] Extract a function from a list and create a call

Douglas Bates bates at stat.wisc.edu
Mon Mar 22 14:14:36 CET 2010


On Mon, Mar 22, 2010 at 3:20 AM, Romain Francois
<romain at r-enthusiasts.com> wrote:
> Le 22/03/10 03:12, Douglas Bates a écrit :
>>
>> On Sat, Mar 20, 2010 at 2:53 AM, Romain Francois
>> <romain at r-enthusiasts.com>  wrote:
>>>
>>> Hello,
>>>
>>> The issue with CharacterVector is that the proxy classes :
>>> "string_name_proxy" and "string_proxy" only have implicit conversion to
>>> SEXP
>>> and char* :
>>>
>>> operator char* (){
>>>        return get() ;
>>> }
>>> operator SEXP(){
>>>        return ::Rf_mkString(get()) ;
>>> }
>>>
>>> i.e. they don't have implicit conversion to std::string. We can't have
>>> both
>>> implicit conversions to char* and std::string because it causes
>>> ambiguities
>>> and the compiler is much unhappy.
>>>
>>> So given a CharacterVector, we can grab the first element as a
>>> std::string
>>> using one of these options:
>>>
>>> require( Rcpp )
>>> require( inline )
>>>
>>> fx<- cfunction( signature( x_ = "character" ), '
>>> CharacterVector x(x_);
>>>
>>> // x[0] is implicitely converted to a char* and the string( char*)
>>> // constructor is used
>>> std::string y( x[0] ) ;
>>>
>>> // using string::operator=( char* ) with a std::string created before
>>> std::string z ;
>>> z = x[0] ;
>>>
>>> // but this does not work
>>> // std::string foo = x[0] ;
>>> // because there is no implicit conversion proxy ->  std::string
>>>
>>> ', Rcpp = TRUE, includes = "using namespace Rcpp;" )
>>
>> I can run your example without a problem but when I try to go to the
>> next stage and extract the character vectors from a list, it seems
>> that internally the conversion to a STRSXP has not been completed (or
>> something like that).  Attempts to extract the first string from the
>> CharacterVector extracted by name from the list fail with an error
>> message of
>>>
>>> fx(binomial())
>>
>> Assigned fam of length 1, llink of length 1
>> Error in fx(binomial()) :
>>   STRING_ELT() can only be applied to a 'character vector', not a 'symbol'
>
> This is worrying. Not sure where the problem is yet.
>
> And when I run the code on OSX (gcc 4.2), I get :
>
>  *** caught segfault ***
> address 0x0, cause 'memory not mapped'
>
> Traceback:
>  1: .Call("file10d63af1", PACKAGE = f, l)
>  2: fx(binomial())
> aborting ...
> Segmentation fault
>
> which is not good either.

It's likely the segfault occurs when trying to create the std::string
from fpt.  A simpler test is

suppressWarnings(require(inline))
suppressWarnings(require(Rcpp))

fx<- cfunction( signature( l = "list" ), '
    List ll(l);
    CharacterVector fam = ll["family"];
    Rprintf("Assigned fam of length %d\\n", fam.size());
    if (!fam.size()) return R_NilValue;
    char *fpt = fam[0];
    Rprintf("(char*)fam[0] points to \\"%s\\"\\n", fpt);
    std::string fstr(fpt);
    Rprintf("std::string fstr points to \\"%s\\"\\n", fstr.c_str());
    return R_NilValue;
', Rcpp = TRUE, includes = "using namespace Rcpp;" )

fx(binomial())

I think the problem under Linux is extracting fam[0].  The error
message to me indicates that even though fam is declared as a
CharacterVector the SEXP it contains isn't a STRSXP.
>
>> The test script is
>>
>> suppressWarnings(require(inline))
>> suppressWarnings(require(Rcpp))
>>
>> fx<- cfunction( signature( l = "list" ), '
>>     List ll(l);
>>     CharacterVector fam = ll["family"], llink = ll["link"];
>>     Rprintf("Assigned fam of length %d, llink of length %d\\n",
>>            fam.size(), llink.size());
>>     char *fpt = (char *)0, *lpt = (char *)0;
>>     if (fam.size()) fpt = fam[0];
>>     if (llink.size()) lpt = llink[0];
>>     return List::create(_["fam"] = std::string(fpt),
>>                         _["llink"] = std::string(lpt));
>> ', Rcpp = TRUE, includes = "using namespace Rcpp;" )
>>
>> fx(binomial())
>> fx(gaussian())
>> fx(poisson())
>
> --
> Romain Francois
> Professional R Enthusiast
> +33(0) 6 28 91 30 30
> http://romainfrancois.blog.free.fr
> |- http://tr.im/OIXN : raster images and RImageJ
> |- http://tr.im/OcQe : Rcpp 0.7.7
> `- http://tr.im/O1wO : highlight 0.1-5
>
>


More information about the Rcpp-devel mailing list