Reputation: 3024
What is the proper way to load in a dynamically linked library (i.e., a .so
file) when writing an R package? The only solution that has worked for me so far has been to specify the full path to the .so
file, e.g.:
dyn.load('/FULL/PATH/TO/MY/R_PACKAGE/src/my_file.so')
Obviously, this approach will not work for a CRAN/Bioconductor submission since the .so file will not be located. As such, I have (unsuccessfully) tried the following alternatives:
1) library.dynam()
2) library.dynam('my_file.so')
3) library.dynam('my_file.so', 'R_PACKAGE')
4) system.file("src", "my_file.so", package = "R_PACKAGE")
Related links: R: C symbol not in load table, R: C symbol name not in load table - error in linking with external .c files.
Just to be crystal clear, users of my R package may obviously set any arbitrary working directory on their computers. The only way a full path approach (as shown above) would ever work is if they set their working directory to /FULL/PATH/TO/MY/R_PACKAGE/src
, which is (of course) impractical.
Upvotes: 2
Views: 826
Reputation: 368251
Quick points:
Why do you need to ship a .so
file? This would preclude uploads to common repos like CRAN which will not accept binary content
You can compute the full /FULL/PATH/TO/MY/R_PACKAGE/src/my_file.so
by using system.file("src", "my_file.so", package="R_PACKAGE")
(but then make sure you actually install a src/
which is not standard)
In all other cases (as pointed out by @BenBolker) R will know how to create the dynamic library and load it for you. Every package with compiled code does that. Just drop your source code into src/
and you are (essentially) done.
Upvotes: 1
Reputation: 226192
The standard way to do this, as described in Writing R Extensions, is:
1.5.4 useDynLib
A
NAMESPACE
file can contain one or moreuseDynLib
directives which allows shared objects that need to be loaded.* The directive
useDynLib(foo)
registers the shared object
foo
** for loading withlibrary.dynam
. Loading of registered object(s) occurs after the package code has been loaded and before running the load hook function. Packages that would only need a load hook function to load a shared object can use theuseDynLib
directive instead.
*
NB: this will only be read in all versions of R if the package contains R code in a R directory.**
Note that this is the basename of the shared object, and the appropriate extension (.so or .dll) will be added.
Upvotes: 1