[R] Calling R from C - part way there but need a push!

Jeffrey Horner jeff.horner at vanderbilt.edu
Wed Apr 30 16:25:26 CEST 2008


Maximillian Murphy wrote on 04/29/2008 11:19 AM:
> 
> Dear All,
> 
> 
> I've read the manual on "Writing R Extensions" and in particular the 
> part on calling R from C.  (Most of the manual is about calling C from 
> R, not the other way around.)
> 
> The good news is that I can now call _some_ R from C, specifically the R 
> functions which have C header files.  However it isn't clear to me how 
> to call R functions that are written in R.  I imagine that there is a 
> standard C function of the form
> 
> Call_r_from_C("package name", "Rfunction name as a string", arg1, arg2, 
> ...);
> 
> where arg1 etc are standardised ways of representing R data structures 
> in C.  However I haven't been able to find such a function prototype in 
> the R include/*.h files.  See footnote (1).  Can you point me in the 
> right direction please?  Is there a set of examples somewhere that I can 
> peruse?
> 
> 
> Does R keep any state when being called from C?  Should I think of it as 
> being a co-process, so I can make consecutive calls to it and expect it 
> to remember previous calls?  I'm thinking of a sequence of calls such as 
> "load library",  "load R code from a file of my own", "set value of x", 
> "make a call and read the values back into my C program"?
> 
> 
> Help is much appreciated.

I would recommend studying the examples found in the tests/Embedding 
directory from the R sources. For instance, the following is from 
RNamedCall.c:

  /*
   Call the function foo() with 3 arguments, 2 of which
   are named.
    foo(pch="+", id = 123, c(T,F))

   Note that PrintValue() of the expression seg-faults.
   We have to set the print name correctly.
*/

void
bar1()
{
     SEXP fun, pch;
     SEXP e;

     PROTECT(e = allocVector(LANGSXP, 4));
     fun = findFun(install("foo"), R_GlobalEnv);
     if(fun == R_NilValue) {
	fprintf(stderr, "No definition for function foo. Source foo.R and save 
the session.\n");
	UNPROTECT(1);
	exit(1);
     }
     SETCAR(e, fun);

     SETCADR(e, mkString("+"));
     SET_TAG(CDR(e), install("pch"));

     SETCADDR(e, ScalarInteger(123));
     SET_TAG(CDR(CDR(e)), install("id"));

     pch = allocVector(LGLSXP, 2);
     LOGICAL(pch)[0] = TRUE;
     LOGICAL(pch)[1] = FALSE;
     SETCADDDR(e, pch);

     PrintValue(e);
     eval(e, R_GlobalEnv);

     SETCAR(e, install("foo"));
     PrintValue(e);
     R_tryEval(e, R_GlobalEnv, NULL);

     UNPROTECT(1);
}

Best,

Jeff

> 
> 
> Regards, Max
> 
> 
> (1) The most likely include file is Rinterface.h and within that the 
> most likely candidates seem to be:
> extern int  (*ptr_R_ReadConsole)(const char *, unsigned char *, int, int);
> extern void (*ptr_R_WriteConsole)(const char *, int);
> extern void (*ptr_R_WriteConsoleEx)(const char *, int, int);
> 
> but it turns out that they assume that R is running the terminal and 
> these are requests to R to display or read from R's console.  R isn't 
> acting as the back end being given work and returning answers.
> 
> (2) Googling "calling r from c" yields precisely five hits, most of 
> which just point back at the R extensions document with vague "It's in 
> there somewhere"'s.  I've looked!
> 
> (3) Leads suggested by help.search("C")
> Foreign(base):
>      Foreign Function Interface  Functions to make calls to compiled 
> code that has been loaded into R.
> 
> .Internal(base)         Call an Internal Function
>      '.Internal' performs a call to an internal code which is built in
>      to the R interpreter.
> 
>      Only true R wizards should even consider using this function, and
>      only R developers can add to the list of internal functions.
> 
>      (Definitely not me!)
> 
> .Primitive(base)        Call a "Primitive" Internal Function
> 
>      The advantage of '.Primitive' over '.Internal' functions is the
>      potential efficiency of argument passing.
> 
> (4) R code that I have called successfully is that with prototypes 
> defined in e.g. include/R_ext/Applic.h
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide 
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.


-- 
http://biostat.mc.vanderbilt.edu/JeffreyHorner



More information about the R-help mailing list