Skip to content

What the Package Does (One Line, Title Case)

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE
MIT
LICENSE.md
Notifications You must be signed in to change notification settings

DavisVaughan/cexport

Repository files navigation

cexport

This README holds an example of:

  • Creating a C function that you can call from R.

  • “Registering” that C callable to be called from another package’s C code.

  • “Getting” the registered C callable and providing an easy header file for other packages to use.

  • Actually calling that function from another package’s C code.

This package implements, registers, and exports the function that will be called in other packages.

The other package that goes along with this one and actually calls the C function from it’s own C code is cexportuser.

You can install this package with:

devtools::install_github("DavisVaughan/cexport")

You can install the companion package that uses this C code (which should “just work” and also install cexport if needed) with:

devtools::install_github("DavisVaughan/cexportuser")

Details

Here are the steps to do this yourself:

  • Create your C function (src/arith.c - cexport_plus_one())

  • Optionally export it to R with the standard R_registerRoutines() (src/init.c) and #' @useDynLib cexport, .registration = TRUE (cexport-package.R).

  • “Register” the C callable with R_RegisterCCallable() so other packages can find it with R_GetCCallable() (src/init.c).

  • At this point, you can either let users call R_GetCCallable() themselves in their own package, or you can be nice and generate a header file that they can just #include to get access to your API.

  • Let’s be nice. In inst/include/cexport.h we create an API function with essentially the same signature as our original function, look up the C callable once, and call the function.

    • We also make the function static so that users can call it from multiple of their C files without throwing any “duplicate symbol” errors.

    • And we R_INLINE the function to reduce the overhead of the C function call. Essentially, once we have called the function once to get the C callable from cexport, repeated calls to the function will be just as fast as calling it natively.

  • Now install the package.

The next section will be from the perspective of a package that is going to be calling cexport_plus_one() from their own C code. That package is cexportuser.

  • In the package that is going to be calling cexport_plus_one(), add LinkingTo: cexport.

  • Now also add Imports: cexport. This is required as you have to fully load cexport to be able to use its C callables.

  • You must also @importFrom something from cexport so it gets loaded. I imported the plus_one() function (cexportuser-package.R).

  • Create your C function that is going to call cexport_plus_one(). At the top of the file put #include <cexport.h>. RStudio should recognize this for you. You can now call cexport_plus_one(). (src/arith.h - cexportuser_plus_two()).

  • Export the C function to R if you want (src/init.c, exported as plus_two() in arith.R).

If all goes well you should be able to do something like:

library(cexportuser)
plus_two(2L)
#> [1] 4

References

A few packages do this, with cleancall probably being the easiest to read:

Also R Extensions has some advice:

And there is some information in R Packages:

About

What the Package Does (One Line, Title Case)

Resources

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE
MIT
LICENSE.md

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published