[Rd] Linking to native routines in other packages

Gregor Kastner gregor.kastner at wu.ac.at
Wed Jan 22 19:56:54 CET 2014


Hi again,

On Wed, 22 Jan 2014 06:39:17 -0600
Dirk Eddelbuettel <edd at debian.org> wrote:

| Working examples I know of:   
| 
|    'xts' importing two functions from 'zoo'
| 
|    'RcppXts' importing approx. ten functions from 'xts'
| 
| Maybe by comparing to these you can sort out the missing step at your end.

Thanks Dirk for the hints; I finally got the code running. Important point
is that R_init_PKGNAME() is declared as extern "C" (or RcppExport, of course)
if using g++ in both the mother and the child package. (Interestingly,
dyn.load() only complains when either the mother or the child package don't
do so, but not if both don't do so => SEGFAULT.) Since it took me almost the
entire afternoon to figure that out, I'll document a working example here. 

Scenario: We have a 'mother' package, which wants to make some C/C++ routines
available to the 'child' package to be called directly from C/C++ level.
Thus, mother's 'src' cointains:


********* BEGIN test.c *********

#include <R.h>
#include <Rinternals.h>
#include <R_ext/Rdynload.h>

SEXP fun(SEXP);

void R_init_mother(DllInfo *dll) {
 R_RegisterCCallable("mother", "fun", (DL_FUNC) &fun);
}

SEXP fun(SEXP test) {
 Rprintf("fun so much fun\n");
 return R_NilValue;
}

********** END test.c **********


(Note that no extern "C" is needed here because it will be compiled with gcc
anyway).

The child uses Rcpp and mother, thus has


********* BEGIN DESCRIPTION *********

LinkingTo: mother, Rcpp
Depends: mother, Rcpp
Imports: mother, Rcpp

********** END DESCRIPTION **********


in its DESCRIPTION file, and 


********* BEGIN test.cpp *********

#include <Rinternals.h>
#include <R_ext/Rdynload.h>

extern "C" {
 SEXP afun(SEXP);
 SEXP(*fun)(SEXP);

 void R_init_child(DllInfo *info) {
  fun = (SEXP(*)(SEXP)) R_GetCCallable("mother", "fun");
 }

 SEXP afun(SEXP test) {
  fun(test);
  return R_NilValue;
 }
}

********** END test.cpp **********

(Note that extern "C" is crucial here.) After installing mother and child, we
have:

> library(child)
Loading required package: mother
Loading required package: Rcpp
> .Call("afun", 123, PACKAGE="child")
fun so much fun
NULL
>

Maybe it is of help to someone; please excuse me if I bored anyone with
trivialities.

Best,
Gregor



More information about the R-devel mailing list