[Rd] Qs on calling R from C

Dirk Eddelbuettel edd at debian.org
Sat Jun 6 23:31:15 CEST 2009


On 6 June 2009 at 17:03, Kynn Jones wrote:
| Consider the following simple C program:
| 
| /*** hello_r.c ***/
| #include <Rinternals.h>
| 
| SEXP hello() {
|  return mkString("Hello, world!\n");
| }
| 
| int main(void) {
|  SEXP x = hello();
|  return x == NULL;             /* i.e. 0 on success */
| }
| 
| This program segfaults:
| 
| % myR/bin/R CMD LINK gcc -I./R-2.9.0/src/include -L./myR/lib64/R/lib -lR
| hello_r.c -o hello_r > /dev/null
| % hello_r
| zsh: segmentation fault  hello_r

The error is in your assumption that because the code below works, the code
above should as well.  That is wrong -- there is more to embedding R than you
do here.

| But if instead of compiling the program as a standalone I make it as a
| shared library, like this:
| 
| % myR/bin/R CMD SHLIB --preclean hello_r.c > /dev/null
| 
| ... then the hello() function works fine, when run from within an R session:
| 
| > dyn.load(paste("hello_r", .Platform$dynlib.ext, sep = ""))
| > .Call("hello")
| [1] "Hello, world!\n"
| 
| 
| The fact that the same function succeeds when run from within an R session
| but segfaults when run from the standalone executable tells me that, in the
| standalone case, the main() function needs to do some initialization stuff
| on R before one can invoke functions like mkString(), but I have not been
| able to find what this initialization should be.
| If someone could point me in the right direction I'd appreciate it.

Try reading 'R Extensions' section 8.1 entitled 'Embedding R under
Unix-alikes'.  

Or you use something like my 'RInside' classes (on r-forge and my website) to
more easily embed R into C++ programs.

| Also, where is the documentation for the call_R function?  It is mentioned
| several times in the Writing R Extensions document, but I have not been able
| to find the documentation for it.

I think that's a C level function in the R sources, so you may have to look
there:

edd at ron:~> grep -rin call_R src/debian/R/R-2.9.0/src/
src/debian/R/R-2.9.0/src/library/base/man/Foreign.Rd:150:  \R functions can be invoked using \code{call_S} or \code{call_R} and
src/debian/R/R-2.9.0/src/library/base/man/Foreign.Rd:170:  \code{call_S}/\code{call_R}.  New code using \R objects should be
src/debian/R/R-2.9.0/src/main/dotcode.c:2409:void call_R(char *func, long nargs, void **arguments, char **modes,
src/debian/R/R-2.9.0/src/main/dotcode.c:2417:   error(_("invalid function in call_R"));
src/debian/R/R-2.9.0/src/main/dotcode.c:2419:   error(_("invalid argument count in call_R"));
src/debian/R/R-2.9.0/src/main/dotcode.c:2421:   error(_("invalid return value count in call_R"));
src/debian/R/R-2.9.0/src/main/dotcode.c:2464:       error(_("mode '%s' is not supported in call_R"), modes[i]);
src/debian/R/R-2.9.0/src/main/dotcode.c:2506:    call_R(func, nargs, arguments, modes, lengths, names, nres, results);
src/debian/R/R-2.9.0/src/main/coerce.c:1317:    errorcall_return(call, R_MSG_mode);
src/debian/R/R-2.9.0/src/main/coerce.c:1363:    errorcall_return(call, R_MSG_mode);
src/debian/R/R-2.9.0/src/main/coerce.c:1769:    errorcall_return(call, R_MSG_mode);
src/debian/R/R-2.9.0/src/main/coerce.c:1812:    errorcall_return(call, "is.na " R_MSG_list_vec);
src/debian/R/R-2.9.0/src/main/coerce.c:1924:    errorcall_return(call, "is.nan " R_MSG_list_vec);
src/debian/R/R-2.9.0/src/main/coerce.c:2019:    errorcall_return(call, "is.finite " R_MSG_list_vec);
src/debian/R/R-2.9.0/src/main/coerce.c:2071:    errorcall_return(call, "is.infinite " R_MSG_list_vec);
src/debian/R/R-2.9.0/src/main/coerce.c:2128:    errorcall_return(call, R_MSG_A1_char);
src/debian/R/R-2.9.0/src/main/complex.c:917:    errorcall_return(call, _("unimplemented complex function"));
src/debian/R/R-2.9.0/src/main/builtin.c:142:    errorcall_return(call, _("invalid number of arguments"));
src/debian/R/R-2.9.0/src/include/Rinternals.h:652:#define errorcall_return(cl,msg){ Rf_errorcall(cl, msg);   return R_NilValue; }
src/debian/R/R-2.9.0/src/include/S.h:73:/* void call_R(char*, long, void**, char**, long*, char**, long, char**);*/
src/debian/R/R-2.9.0/src/include/S.h:74:#define call_S call_R
src/debian/R/R-2.9.0/src/include/R_ext/RS.h:86:void     call_R(char*, long, void**, char**, long*, char**, long, char**);

Hth, Dirk

-- 
Three out of two people have difficulties with fractions.



More information about the R-devel mailing list