Re: [Rd] Embedding R and registering routines from Simon Urbanek on 2007-05-02 (R devel archive)

Re: [Rd] Embedding R and registering routines

From: Simon Urbanek <simon.urbanek_at_r-project.org>
Date: Tue, 01 May 2007 15:22:54 -0400

Since I'm not sure I really understand Jeff's question this is just my interpretation, but I think the point was that you may want to register symbols *not* from a DLL but from the embedding application itself (e.g. like R.app GUI that embeds libR registers its entry for quartz.save). I would welcome a support for this, because the current dirty hack (don't do this at home, kids!) is to use R_getDllInfo ("base") and append the entry instead of overwriting it. It is an ugly hack, but I don't think we have any API for this. Maybe a worthwhile endeavor would be to simply add something like R_getDllInfo ("embedded") reserved specifically for such purposes (or "R" or whatever...).

Cheers,
Simon

On May 1, 2007, at 1:56 PM, Duncan Temple Lang wrote:

> Jeffrey Horner wrote:
>> Hello,
>>
>> The use of .Call and the like all depend on loading shared
>> libraries and
>> registering routines from it. Also, .Primitive and .Internal
>> depend on
>> routines being registered in the R binary. And applications that
>> embed R
>> can override routines declared in Rinterfac.h, but is there a way
>> for an
>> application embedding R to register other routines defined in the
>> application without loading a shared library or re-compiling R?
>
> I think I understand the question, and if so, the answer is yes!
>
> I have put some code near the end of the message that illustrates
> (tests) this idea.
>
> The basic idea is that after you initialize R and load your
> RApache package with its .so, you can ask for the corresponding
> DllInfo object for that RApache.so. (You need the full path.)
>
> Then, you call R_registerRoutines() with that object as the first
> argument and your collection of routines for .C, .Call, .Fortran, etc.
> And then those routines are available to R via the corresponding
> interface function.
>
> This is currently slightly strained in two ways.
>
> Firstly, R_registerRoutines() just overwrites any existing registered
> entries. So we should have something that allows us to append to
> this. We could add something, if this is a worthwhile approach and
> others want to chime in with comments.
>
> Also we are adding these symbols to a table to which they do not
> really belong, i.e. pretending they are the same as the routines in
> RApache.so. But it works. Ideally, we would like to be able to create
> and add our own special type of DllInfo. A class system from an
> object-oriented language would really help here. But we also would
> need to make this possible via the R API.
>
>
> (Another hacky, unreliable way is using global symbols.
> It is possible for R to resolve symbols on some platforms
> by looking in the application's global symbol table.
> So R could find symbols in the executable. Of course, you load
> mod_R.so and so its symbols are not likely to be in the global symbol
> as I doubt very much Apache loads modules globally.
> And we would also have to bed R slightly to make this work.
> )
>
>
> main.c:
> -----------------------------
> #include <Rinternals.h>
> #include <Rembedded.h>
> #include <R_ext/Rdynload.h>
>
> void
> foo(int *x)
> {
> fprintf(stderr, "In foo\n");
> *x = 101;
> }
>
> SEXP
> bar(SEXP n)
> {
> return(ScalarInteger(INTEGER(n)[0] * 2));
> }
>
> void
> unregistered()
> {
> fprintf(stderr, "In unregistered\n");
> }
>
> static R_CallMethodDef callMethods[] = {
> {"bar", (DL_FUNC) &bar, 1},
> {NULL, NULL, 0}
> };
>
> static R_CMethodDef cmethods[] = {
> {"foo", (DL_FUNC) &foo, 1}, /* type { INTSXP }*/
> {NULL, NULL, 0}
> };
>
> void
> registerApplicationRoutinesWithR()
> {
> DllInfo *dll;
> dll = R_getDllInfo("/home/duncan/Rpackage/XML/libs/XML.so");
> R_registerRoutines(dll, cmethods, callMethods, NULL, NULL);
> }
>
> int
> main(int argc, char *argv[])
> {
> int errorOccurred = 0;
> SEXP e;
> Rf_initEmbeddedR(argc, argv);
> registerApplicationRoutinesWithR();
>
> PROTECT(e = allocVector(LANGSXP, 2));
> SETCAR(e, Rf_install("source"));
> SETCAR(CDR(e), mkString("test.R"));
> R_tryEval(e, R_GlobalEnv, &errorOccurred);
>
> return(0);
> }
>
>
> test.R:
> ---------------------------
> print(.C("foo", x= as.integer(1))$x)
> print(.Call("bar", as.integer(3)))
>
>
>
>
> GNUmakefile:
> -------------------------------------
>
> CFLAGS=-g -I$(R_HOME)/include
>
> main: main.o
> $(CC) -o $@ $^ -L$(R_HOME)/lib -lR
>
>>
>> The only such way I've found that comes close to a solution to
>> this is
>> creating an RObjectTable and attaching that to the search path.
>> Assignments to variables in that environment can call the table's get
>> routine which is defined in the application, and I think that
>> might be
>> an interesting solution for a new RApache implementation.
>>
>> For the RApache Project, the mod_R.c shared library get's loaded into
>> the apache process and its purpose is to initializes R. Next, it
>> calls
>> 'library(RApache)' to load RApache.so, a package that implements the
>> RApache API. This two-library system works, but the implementation is
>> too complex. I'd like to simplify down to just one shared library.
>>
>> Any comments, suggestion are much appreciated.
>>
>> Thanks,
>>
>> Jeff
>> --
>>
http://biostat.mc.vanderbilt.edu/JeffreyHorner
>>
>> ______________________________________________
>> 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
> 4210 Mathematical Sciences Bldg. fax: (530) 752-7099
> One Shields Ave.
> University of California at Davis
> Davis, CA 95616, USA
>
>
>
> ______________________________________________
> R-devel_at_r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Tue 01 May 2007 - 19:28:03 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Tue 01 May 2007 - 21:33:58 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.