From duncan at wald.ucdavis.edu  Wed Aug 17 09:15:29 2005
From: duncan at wald.ucdavis.edu (Duncan Temple Lang)
Date: Wed, 17 Aug 2005 00:15:29 -0700
Subject: [Rd] About R variable references
In-Reply-To: <000001c5a2f7$b2407e00$e101a8c0@MARKKUNOTEBOOK>
References: <000001c5a2f7$b2407e00$e101a8c0@MARKKUNOTEBOOK>
Message-ID: <20050817071529.GE2941@wald.ucdavis.edu>

Hi Markku.

  You have correctly diagnosed the problem that the initially
set global variables "are not stable".  In your call
to myinit, you store a C-level reference to the var and func
R objects. But you need to tell R's memory management
that you need to hold onto them.  Otherwise it is entitled
to garbage collect them as it feels fit. 
In the C-code for myinit, you might add calls 

    R_PreserveObject(myfunction)
    R_PreserveObject(myvariable)

that is defined in Rinternals.h. These go after
you assign values to your global variables.

You are PROTECT()'ing these variables only in the call
to myexec.

 D.
 

Markku Mielityinen wrote:
> Hello Group,
> 
> I could use an advice on how SEXP handles work. My aim is to implement a
> system where I initially set a few global variables that are used for
> communication between C and R code. Then I do some work with R code and
> periodically call a function of my own that will update the system
> state. Such a design is useful for many purposes (for GUIs to name one).
> I am not entirely sure that R can handle such a design but at the moment
> I cannot see any reasons why it could not. The problem I have is that
> the initially set global variables are not stable. Everything works for
> a while but eventually the system gets confused. It seems that the SEXP
> references to the state variables and to the callback functions may get
> altered and become pointing to some other variables. This will then
> rightfully give me the error messages like "attempt to apply
> non-function". My (maybe uneducated) guess is that this might have
> something to do with R memory management. The variables are connected to
> the namespace so a do not think they are removed. Maybe they are moved
> is such a way that my SEXP references are not able to follow. As you can
> see I am on thin ice here so please feel welcome to step in...
> 
> My librtary contains ~20k lines of C code so I would not consider a bug
> here out of the question. I have tried to look for one but until now
> without success.
> 
> My question is: can you see a design flaw here or is everything done
> according to R requirements and hence it is likely that there is a bug
> in my own code?
> 
> One dirty correction I can see but have not tried is to use object names
> and findVar but this would make it less flexible (at least IMHO).
> 
> I have quickly browsed the forums and the documentation I was able to
> find but found no answers.
> 
> My system is FC3 with R version >= 2.
> 
> There are two snippets of code that hopefully make clear what I am
> trying to achieve. The code is provided for illustration purposes only
> and I did not try to compile it.
> 
> Best regards,
>         Markku Mielityinen
> 
> 
> #  C CODE
> #####################################################################
> 
> SEXP myrho = R_GlobalEnv;
> SEXP myvariable = R_NilValue;
> SEXP myfunction = R_NilValue;
> 
> SEXP myinit(SEXP var, SEXP func) {
> 	myvariable = var;
> 	myfunction = func;
> 	return R_NilValue;
> }
> 
> SEXP myexec(/* probably has some parameters that are omitted in this
> example */) {
> 	int state;
> 	SEXP thecall;
> 	
> 	/* do some work, then set the state and call a callback function
> if necessary */
> 	
> 	PROTECT(myvariable);
> 	INTEGER(myvariable)[0] = state;
> 	UNPROTECT(1);
> 	if(state) {
> 		PROTECT(thecall = LCONS(myfunction, LCONS(myvariable,
> R_NilValue)));
> 		eval(thecall, myrho);
> 		UNPROTECT(1);
> 	}
> 
> 	return R_NilValue;
> }
> 
> ########################################################################
> ########
> 
> #  R CODE
> #####################################################################
> 
> myinit<-function(var,func) .Call("myinit",var,func)
> myexec<-function() .Call("myexec")
> 
> state<-as.integer(1)
> callback<-function(state) { cat(sprintf("You got state %s\n",state)) }
> 
> myinit()
> # do some work here and call myexec() periodically...
> 
> ########################################################################
> ########
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
Duncan Temple Lang                duncan at wald.ucdavis.edu
Department of Statistics          work:  (530) 752-4782
371 Kerr Hall                     fax:   (530) 752-7099
One Shields Ave.
University of California at Davis
Davis, CA 95616, USA



-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : https://stat.ethz.ch/pipermail/r-devel/attachments/20050817/35eda213/attachment.bin


[Rd] About R variable references
Duncan Temple Lang