On 26/05/2009 5:13 PM, Richard Morey wrote:
Hi everyone,
I am starting learn to call C code from within R. So far, I've been
trying toy problems to see if I can get them to work. One of the things
I'd like to do is pass an arbitrary R function to C, evaluate the value
in the C code using eval, and then return it. I also want to allow an
arbitrary number of arguments to the function using "...".
The code for my toy package looks like this:
########## R code, in pkg/R directory
dTest <-
function(x,...){
retVal = .Call("dTestC",x[1],dnorm,...,rho=new.env(),PACKAGE="pkg")
return(retVal)
}
########## C code, in pkg/src directory
SEXP dTestC(SEXP dblX, SEXP funFn, SEXP dots, SEXP rho);
I wouldn't expect that to work, though it might if .Call is doing fancy
things with the args. The way I'd do it is to pass list(...) as a
single argument to .Call, and within your C code, extract the elements.
It would make the call to funFn more complicated (it wants a pairlist
of arguments, list(...) will be a vector list), but it looks safer than
what you did.
There's an example in the Writing R Externals manual at the end of
section 5.10.2 using ... with .External. (It mentions using list(...)
with .Call.)
Duncan Murdoch
/*--------------------------*/
SEXP dTestC(SEXP dblX, SEXP funFn, SEXP dots, SEXP rho){
SEXP retVal;
SEXP R_fcall;
PROTECT(retVal = NEW_NUMERIC(1));
PROTECT(R_fcall = lang3(funFn, R_NilValue, R_NilValue));
SETCADR(R_fcall, dblX);
SETCADDR(R_fcall, dots);
retVal = eval(R_fcall, rho);
UNPROTECT(2);
return(retVal);
}
########################
When I call the dTest() function, the first required argument and the
first optional argument are both used, but not the ones after that.
I'm modeling this after what I found in the 'HI' package. I don't
understand a few few things. First, the C code used by the arms()
function in the HI package somehow manages to evaluate an R function,
with "..." arguments, without passing the SEXP dots argument. I haven't
been able to figure out how, looking at the source.
Second, in the Rinternal documents it mentions that "..." is one
argument. So, I figured I could get away with doing what I've done
above, and the SETCADDR function would set all the arguments in "..." in
one go. This is evidently wrong.
How can I do what I want to do? I know the HI package does it, but I
don't know how. I might pass all the arguments as members of one list,
but that seems like a waste. What am I doing/thinking wrong here? What's
the best way to do what I want to do?
Thanks for your help,
Richard
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel