Skip to content

Instantly share code, notes, and snippets.

Created July 26, 2011 17:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/1107238 to your computer and use it in GitHub Desktop.
Save anonymous/1107238 to your computer and use it in GitHub Desktop.
Dan Adler's recent work on the Foreign Function Interface for R
Initial Announcement: Package rdyncall released on CRAN. (Version 0.7.3)
The package was presented at the Use!R 2009 with the title
'An improved Foreign Function Interface for R' and is now available on CRAN
and considered stable for a large range of R platforms.
The package provides a cross-platform framework for dynamic binding of
C libraries using a flexible Foreign Function Interface (FFI).
The FFI supports almost all fundamental C types, multiple calling conventions,
symbolic access to foreign C struct/union data types and wrapping of R fun-
ctions as C callback function pointers.
Dynamic bindings to shared C libraries and the C APIa are data-driven by
cross-platform binding specification using a compact plain text format.
The interface consists of a single function, similar to 'library':
> dynport(portname)
where 'portname' refers to a name of a C API binding specification;
an initial repository of DynPorts to a couple of common C libraries comes
with the package:
DynPort Description
expat Expat XML Parser Library
GL OpenGL 1.1 API
GLU OpenGL Utility Library
SDL Simple DirectMedia Layer library
SDL_image Loading of image files (png,jpeg..)
SDL_mixer Loading/Playing of ogg/mp3/mod/xm music files.
SDL_ttf Loading/Rendering of True Type Fonts.
glew OpenGL Extension Wrangler (includes OpenGL 3)
gl3 strict OpenGL 3
R R shared library
ode Open Dynamics (Physics-) Engine (untested)
cuda NVIDIA Cuda (untested)
opencl OpenCL (untested)
stdio C Standard Library I/O Functions
The R programming interface of bindings looks very similar to C.
'dynport()' dynamically creates and attaches an R namespace that is
populated with lightweight R helper objects (with similar name) to
C entities such as:
- dynamically linked and resolved C functions,
- symbolic constants (macro definitions and enums) and
- struct/union type information objects (allocation and symbolic access).
The R bindings work across platforms. The host system need to have the C
shared libraries pre-installed. For OS-specific details on this, see
manual page on 'rdyncall-demos' (type: ?'rdyncall-demos').
The package includes a variety of technology demos via demo()..
demo Description
SDL 3D rotating cube using SDL, OpenGL and GLU.
randomfield 512x512 random field matrix generator via blending 5000
textures using OpenGL (10-50 fps) and transfer to R.
expat Parsing XML using expat and callbacks.
Win32PlaySound Win32 demo, playing a wav file.
intro Texture-mapped scroller while playing a nice tune(XM module).
qsort C standard library qsort C with a custom compare via
callbacks
A complete showcase of a cross-platform audio/visual 'Demo',
written in 100% pure R using rdyncall, SDL libraries and OpenGL is available
with source, instructions and a video screencast at:
http://dyncall.org/demos/soulsalicious/
The package enables R developers to develop system-level software directly in R
via powerful tools for dynamic interoperability with the C language:
- flexible and more type-safe alternative for '.C()', see '.dyncall()'.
- handling of C struct/union types from R, see 'new.struct()'.
- manipulation of low-level C data, see '.pack()'.
- wrap R functions as C callback pointers, see 'new.callback()'.
- name/load shared libraries cross-platform, see 'dynfind()'.
The manual and a vignette on 'Foreign Library Interface' (vignette('FLI')) give
detailed information.
Details on Portability and Platform Support
-------------------------------------------
The implementation is based on libraries from the DynCall Project that
use a small amount of code in Assembly to offer a generic solution
for dynamic function calls (dyncall) and callback handling (dyncallback)
for a particular binary platform and calling convention.
Once a library is ported, a universal solution becomes available that
uses very small amount of native code; the R package consists of approx.
60kb native code including (dynload, dyncallback and R <-> C value type
mappings).
We use a suite of testing tools to assert a correct implementation of
the call and callback back-ends by checking a large number of cases
with different number and types of argument/return types to ensure
a correct passing between caller and callee.
The cross-platform portability for bindings work at the abstract C type
system layer without defining the exact bit size.
The interface of the dyncall libraries uses this layer to
prepare concrete calls and callbacks with appropriate size and layout.
The bindings are automatically extracted from C header files using a
chain of tools including GCC_XML.
More information on DynCall including a manual, more bindings etc..
see http://dyncall.org
Examples of dyncall bindings for other languages (lua, python, ruby) are
available in the subversion source trunk.
Supported Operating-Systems
---------------------------
The R Package has been tested on several major 32- and 64-bit R platforms
including
- Mac OS X 10.4-6 (ppc32, i386, amd64)
- Windows 32/64-bit
- Linux [Debian,Ubuntu,Fedora,Gentoo] (i386,amd64,ppc32,arm)
- NetBSD (i386,amd64)
- OpenBSD (i386,amd64)
- Solaris (i386,amd64) [to a limited degree]
The DynCall libraries are tested on Linux, Mac OS X, Windows, BSD derivates,
Solaris and more exotic platforms such as Playstation Portable, Nintendo DS,
Plan9, Haiku and Minix.
Details on supported Processor-Architectures and Calling-Conventions:
---------------------------------------------------------------------
- Intel i386: cdecl,stdcall,fastcall (msvc/gcc),thiscall (msvc/gcc),plan9
- AMD64: x64 (Win64), System V
- PowerPC 32-bit: Mac OS X, System V
- ARM 32-bit ARM/Thumb (>= armv4t, no armv7 support currently): aapcs
- MIPS 32-bit: o32, eabi
- MIPS 64-bit: n64
- SPARC 32-bit: v7/v8
- SPARC 64-bit: v9
NOTE: 'System V' is the standard ABI/C calling convention on ELF-based systems
such as Linux, BSDs, Solaris and also the ABI on Mac OS X/amd64.
All i386 platforms except plan9 use cdecl for C (and we do 16-byte alignment
to be compatible with Mac OS X and GCC >= 3.0).
As of this release, no support for callbacks (wrapping R functions as
C function pointers) is available on MIPS or SPARC.
Callbacks on PowerPC 32-bit for Mac OS X work fine, for other
ELF/System V-based PowerPC systems, callbacks are not yet implemented.
Known Bugs
----------
* PowerPC/Mac OS X 10.4: Building Universal Binaries are broken.. in particular
the as for i386 assembly.
Workaround for PowerPC users: install with "--no-multiarch" or use prebuilt
binaries built on OS X >= 10.5.
* SPARC Assembly sources are currently implemented for GNU assembler; they
are not compatible with 'fbe' Sun Assembler on Solaris.
* SDL demos fail on OpenBSD 4.8 due to pthread issues.
Help and Feedback
-----------------
The package comprises new methods for dynamic binding of native code to R
that were designed to work cross-platform. It required intensive
testing on a large range of processor/OS/tool-chain combinations.
It was (and still is!) also very helpful to run tests on different
'distributions' of the same OS for checking e.g. the search algorithm for
locating shared libraries by a short name across operating-systems
(see '?dynfind' for details on this).
I am very thankful for any feedback including bug-reports, success and
failure stories or ideas of improvements. If you feel that an important
architecture, platform or build-tool is missing here please let me know too.
The DynCall authors appreciate any support that helps with porting the DynCall
libraries and the R package e.g. remote development accounts to interesting
platforms, qemu/gxemul images, borrowed/sponsored hardware.
In particular we are currently looking for the following arch/os/compilers
environment for porting the DynCall libraries and rdyncall:
- Sparc/Solaris/SunPro
- PowerPC/AIX/XL C
- MIPS/IRIX/MIPSpro
ChangeLog
---------
0.7.3: [2011-07-19] Added vignette, new ports, new tool-chain an fixes for bugs
o bugfix for Fedora/x64: added search path 'lib64' folder for 'dynfind'.
o added support for Sun make, DynCall uses Makefile.embedded.
o added sparc and sparc64 support using gcc tool-chain.
o added support for amd64 using solaris tool-chain.
o added vignette "foreign library interface".
o bugfix for solaris/x64: added search path 'amd64' folder for 'dynfind'.
o bugfix in examples for libm using 'm.so.6' besides 'm' on unix
(needed by debian 6 sid unstable)
0.7.2: [2011-04-27] Minor fixes
o added win64/mingw64 support.
0.7.1: [2011-04-26] Minor fixes
o minor Makevars fix for parallel builds.
0.7.0: [2011-04-20] Initial Release
o first upload to CRAN.
enjoy,
- Daniel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment