From romain at r-enthusiasts.com  Tue Nov 16 10:04:23 2010
From: romain at r-enthusiasts.com (Romain Francois)
Date: Tue, 16 Nov 2010 10:04:23 +0100
Subject: [Rd] SEXP and slots
In-Reply-To: <4CE194C7.30300@r-enthusiasts.com>
References: <4CE194C7.30300@r-enthusiasts.com>
Message-ID: <4CE24917.60701@r-enthusiasts.com>

Le 15/11/10 21:15, Romain Francois a ?crit :
>
> Hello,
>
> Since people have whisperred about Rcpp, I'd like to play too.
>
>> On 11/15/2010 07:45 AM, Patrick Leyshock wrote:
>>> Very helpful, thank you.
>>>
>>> A couple other questions, please:
>>>
>>> 1. I've got a function written in C, named "my_c_function". In my R
>>> code I call this function, passing to it an INTSXP and a STRSXP,
>>> respectively:
>>>
>>> result <- .Call("my_c_function", int_vector, str_vector)
>>>
>>> The prototype of "my_c_function" is:
>>>
>>> SEXP my_c_function(SEXP int_vec, SEXP str_vec);
>>>
>>> Within my_c_function I am able to extract the values within the integer
>>> vector, e.g. I can grab the first value with these lines of code:
>>>
>>> int extracted_value;
>>> extracted_value = *INTEGER(int_vec);
>>>
>>> What I cannot figure out how to do is extract the value from the
>>> STRSXP. I'm assuming that I can create a pointer to a character array,
>>> then malloc enough memory to hold the value. Is there an analogous
>>> operation on "INTEGER" for STRSXPs?
>>
>> STRING_ELT(str_vec, 0)
>>
>> gets the 0th component of str_vec, which is a CHARSXP, i.e., an SEXP for
>> a character string. The char* can be retrieved with CHAR, so the usual
>> paradigm is
>>
>> const char *x = CHAR(STRING_ELT(str_vec, 0));
>>
>> note the const-ness of the char* -- it's not mutable, because R is
>> managing char * memory.
>>
>> The converse action, of assigning to an element, is
>>
>> SET_STRING_ELT(str_vec, 0, mkChar("foo"));
>>
>> mkChar() is creating a copy (if necessary) of "foo", managing it, and
>> returning a CHARSXP. Working through protection (which will likely be
>> your next obstacle ;) in this last example is a good exercise.
>
> In Rcpp, you would wrap up the STRSXP into a CharacterVector and then
> pull things in and out using indexing:
>
> Rcpp::CharacterVector aladdin(str_vec) ;
> std::string first = aladdin[0] ;
> aladdin[0] = "foobar" ;

As it was pointed out to me offlist, the code above fails to compile. 
This is what you get when you reply to emails while watching a Woody 
Allen movie ...

Anyway, the reason for this is that the line:

std::string first = aladdin[0] ;

uses the __constructor__ of std::string and not the assignment operator. 
The code below does work :

std::string first ;
Rcpp::CharacterVector aladdin(str_vec) ;
first = aladdin[0] ;
aladdin[0] = "foobar" ;


Romain

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/9VOd3l : ZAT! 2010
|- http://bit.ly/c6DzuX : Impressionnism with R
`- http://bit.ly/czHPM7 : Rcpp Google tech talk on youtube



[Rd] SEXP and slots
Romain Francois