[Rcpp-devel] Extract a function from a list and create a call
Douglas Bates
bates at stat.wisc.edu
Mon Mar 22 23:29:42 CET 2010
On Mon, Mar 22, 2010 at 10:21 AM, Romain Francois
<romain.francois at dbmail.com> wrote:
> Le 22/03/10 14:14, Douglas Bates a écrit :
>>
>> 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.
>
> This is not supposed to happen. The constructor of CharacterVector makes
> sure the SEXP is a STRSXP.
>
> Vector( SEXP x ) : Base() {
> Base::setSEXP( r_cast<RTYPE>( x ) ) ;
> }
>
> and r_cast attempts to convert x to a STRSXP and throws otherwise.
>
>
>
>
> When we do :
>
> List ll(l) ;
> CharacterVector fam = ll["family"] ;
>
> ll["family"] makes a generic_name_proxy, we then ask to convert it to a
> CharacterVector, so the templated conversion operator is called :
>
> template <typename T>
> operator T(){
> return ::Rcpp::as<T>( get() ) ;
> }
>
> with T = CharacterVector, so then as<CharacterVector> is called, which
> eventually calls CharacterVector( SEXP) constructor, so fam should refer to
> a STRSXP.
>
>
>
>
> You can do things like this to debug further.
>
> Function str("str") ;
> Rf_PrintValue( str( fam ) ) ;
>
> to check.
>
> or maybe even use the internal inspect:
>
> inspect <- function(...) .Internal(inspect(...))
>
>
> Function inspect("inspect") ;
> Rf_PrintValue( inspect( fam ) ) ;
Thanks for the suggestions. I should have realized that I can call
str and inspect from within a C++ program compiled against Rcpp but I
am still getting used to the flexibility that Rcpp offers.
My test function is now
inspect <- function(...) .Internal(inspect(...))
fx <- cfunction( signature( l = "list" ), '
Function str("str"), inspect("inspect");
List ll(l);
CharacterVector fam = ll["family"];
Rprintf("Assigned fam of length %d\\n", fam.size());
Rf_PrintValue(str(fam));
Rf_PrintValue(inspect(fam));
char *fpt = (char *)0;
Rprintf("Initialized char * pointer to zero\\n");
if (fam.size()) fpt = fam[0];
Rprintf("Assigned fpt\\n");
return R_NilValue;
//List::create(_["fam"] = std::string(fpt));
', Rcpp = TRUE, includes = "using namespace Rcpp;" )
and this segfaults on an Ubuntu (karmic) amd64 running a locally
compiled R-devel.
> sessionInfo()
R version 2.11.0 Under development (unstable) (2010-03-18 r51313)
x86_64-unknown-linux-gnu
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=C LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] Rcpp_0.7.10.3 inline_0.3.4
> fx(binomial())
Assigned fam of length 1
chr "binomial"
NULL
@2acb128 16 STRSXP g0c1 [NAM(2)] (len=1, tl=0)
@2d39830 09 CHARSXP g0c2 [MARK,gp=0x21,ATT] "binomial"
[1] "binomial"
Initialized char * pointer to zero
*** caught segfault ***
address (nil), cause 'memory not mapped'
Traceback:
1: .Call("file327b23c6", PACKAGE = f, l)
2: fx(binomial())
It looks as if the segfault is occurring when extracting a char *
pointer for fam[0]. I don't know if the problem is in the fam[0]
operation or the extracting a char *.
More information about the Rcpp-devel
mailing list