# 37 SWIG and R

- Bugs
- Using R and SWIG
- Precompiling large R files
- General policy
- Language conventions
- C++ classes
- Enumerations

R is a GPL'ed open source statistical and plotting environment. Information about R can be found at www.r-project.org. The R bindings are under active development. They have been used to compile and run an R interface to QuantLib running on Mandriva Linux with gcc. The R bindings also work on Microsoft Windows using Visual C++.

## 37.1 Bugs

Currently the following features are not implemented or broken:

- Garbage collection of created objects
- C Array wrappings

## 37.2 Using R and SWIG

To use R and SWIG in C mode, execute the following commands where example.c is the name of the file with the functions in them

    swig -r example.i
    R CMD SHLIB example_wrap.c example.c

The corresponding options for C++ mode are

    swig -c++ -r -o example_wrap.cpp example.i
    R CMD SHLIB example_wrap.cpp example.cpp

Note that R is sensitive to the names of the files. The name of the wrapper file must be the name of the library unless you use the -o option to R when building the library, for example:

    swig -c++ -r -o example_wrap.cpp example.i
    R CMD SHLIB -o example.so example_wrap.cpp example.cpp

R is also sensitive to the name of the file extension in C and C++ mode. In C++ mode, the file extension must be .cpp rather than .cxx for the R compile command to recognize it. If your C++ code is in a file using something other than a .cpp extension, then it may still work using PKG_LIBS:

    swig -c++ -r -o example_wrap.cpp example.i
    PKG_LIBS="example.cxx" R CMD SHLIB -o example example_wrap.cpp

The commands produces two files. A dynamic shared object file called example.so, or example.dll, and an R wrapper file called example.R. To load these files, start up R and type in the following commands

    dyn.load(paste("example", .Platform$dynlib.ext, sep=""))
    source("example.R")
    cacheMetaData(1)

The cacheMetaData(1) will cause R to refresh its object tables. Without it, inheritance of wrapped objects may fail.

These two files can be loaded in any order

If you are compiling code yourself (not using R itself), there are a few things to watch out for:

- The output shared library name (to the left of the file extension) MUST match the module name, or alternatively, you can also set the -package NAME command line argument. See swig -r -help for more information
- If you do not set the output file name appropriately, you might see errors like

      > fact(4)
      Error in .Call("R_swig_fact", s_arg1, as.logical(.copy), PACKAGE = "example") :
        "R_swig_fact" not available for .Call() for package "example"

- Make sure the architecture of the shared library(x64 for instance), matches the architecture of the R program you want to load your shared library into

## 37.3 Precompiling large R files

In cases where the R file is large, one make save a lot of loading time by precompiling the R wrapper. This can be done by creating the file makeRData.R which contains the following

    source('BigFile.R')
    save(list=ls(all=TRUE),file="BigFile.RData", compress=TRUE)
    q(save="no")

This will generate a compiled R file called BigFile.RData that will save a large amount of loading time.

## 37.4 General policy

The general policy of the module is to treat the C/C++ as a basic wrapping over the underlying functions and rely on the R type system to provide R syntax.

## 37.5 Language conventions

getitem and setitem use C++ conventions (i.e. zero based indices). [<- and [ are overloaded to allow for R syntax (one based indices and slices)

## 37.6 C++ classes

C++ objects are implemented as external pointer objects with the class being the mangled name of the class. The C++ classes are encapsulated as an SEXP with an external pointer type. The class is the mangled name of the class. The nice thing about R is that is allows you to keep track of the pointer object which removes the necessity for a lot of the proxy class baggage you see in other languages.

## 37.7 Enumerations

enumerations are characters which are then converted back and forth to ints before calling the C routines. All of the enumeration code is done in R.