From simon.urbanek at r-project.org  Sun Jun 30 16:29:09 2013
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Sun, 30 Jun 2013 10:29:09 -0400
Subject: [Rd] Save R Objects in C Code
In-Reply-To: <000001ce74db$5c795b40$156c11c0$@gmail.com>
References: <000301ce7245$a9a92eb0$fcfb8c10$@gmail.com>
	<51CAA6E6.6040303@stats.ox.ac.uk>
	<000001ce74db$5c795b40$156c11c0$@gmail.com>
Message-ID: <54D8EA0D-8E74-4FBE-9091-CB151847F75F@r-project.org>

On Jun 29, 2013, at 11:14 AM, Ziqiang Zhao wrote:

> Thanks for your help.
> Since I don't know how to reference the current environment, I create a new
> one to do so.
> It seems that it works.
> Not sure if it is helpful to anyone else out there, but here is my solution:

There are tons of issues with this (first I meant to point them all out but then realized it would make the e-mail 10-times longer than the original code). So to other readers, do not use that code! Not only is it ugly, but it has overflows, leaks and it uses API calls that do something entirely different than what the author thought they do. In addition, you really don't want to be parsing anything - you can construct LANGSXP directly with the values - there are examples in R-exts how to do that properly. As for the environment - if you don't know what you're doing, just use R_GlobalEnv - it's the closes to what most people need (if you need something else then you know how to get that env ;)).

Cheers,
Simon


> SEXP Save(SEXP X,SEXP File)
> {
> 	char Name='X';
> 
> 	SEXP EnvList;
> 	PROTECT(EnvList=allocList(1));
> 	SET_TAG(EnvList,install(&Name));
> 	SETCAR(EnvList,X);
> 
> 	SEXP Env;
> 	PROTECT(Env=allocSExp(ENVSXP));
> 	SET_FRAME(Env,EnvList);
> 	SET_ENCLOS(Env,R_BaseEnv);
> 	SET_HASHTAB(Env,R_NilValue);
> 	SET_ATTRIB(Env,R_NilValue);
> 
> 	int L=length(STRING_ELT(File,0));
> 
> 	char *CMD=(char *)malloc((L+18)*sizeof(double));
> 	CMD[0]='s';CMD[1]='a';
> CMD[2]='v';CMD[3]='e';CMD[4]='(';CMD[5]='X';CMD[6]=',';CMD[7]='f';CMD[8]='i'
> ;CMD[9]='l';CMD[10]='e';CMD[11]='=';CMD[12]='"';
> 	for(int k=0;k<L;k++)
> 	{
> 		CMD[k+13]=CHAR(STRING_ELT(File,0))[k];
> 	}
> 	CMD[L+13]='"';	CMD[L+14]=')';	CMD[L+15]=';';
> CMD[L+16]='\n';CMD[L+17]='\0';
> 
> 	SEXP RCMD,REXP;
> 	PROTECT(RCMD=allocVector(STRSXP,1));
> 	SET_STRING_ELT(RCMD,0,mkChar(CMD));
> 	ParseStatus Status;
> 	REXP=PROTECT(R_ParseVector(RCMD,-1,&Status,R_NilValue));
> 	eval(VECTOR_ELT(REXP,0),Env);
> 	UNPROTECT(4);
> 	return R_NilValue;
> }
> 
> --------------------
> Ziqiang Zhao
> 2013-06-29
> 
> -----Original Message-----
> From: Prof Brian Ripley [mailto:ripley at stats.ox.ac.uk] 
> Sent: Wednesday, June 26, 2013 4:32 PM
> To: johnzhao2835 at gmail.com
> Cc: r-devel at r-project.org
> Subject: Re: [Rd] Save R Objects in C Code
> 
> On 26/06/2013 09:17, Ziqiang Zhao wrote:
>> Dear all,
>> 
>>                 How do I save the R objects in C code?
>> 
>>                 In R code, we use save(x,y,file="F.RData") to save x 
>> and y in "F.RData".
>> 
>>                 But what should I do in C?
> 
> Call that R code (using eval).
> 
> If you look at the R code for save() you will see that a substantial amount
> of it is interpreted code.
> 
>> 
>> --------------------
>> 
>> Ziqiang Zhao
>> 
>> 2013-06-26
>> 
>> 
>> 
>> 
>> 	[[alternative HTML version deleted]]
> 
> Please see the posting guide and what it says about HTML mail.
> 
> -- 
> Brian D. Ripley,                  ripley at stats.ox.ac.uk
> Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
> University of Oxford,             Tel:  +44 1865 272861 (self)
> 1 South Parks Road,                     +44 1865 272866 (PA)
> Oxford OX1 3TG, UK                Fax:  +44 1865 272595
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 
> 



[Rd] Save R Objects in C Code
Simon Urbanek