1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SWIG and R</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body bgcolor="#ffffff">
<H1><a name="R">37 SWIG and R</a></H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#R_nn2">Bugs</a>
<li><a href="#R_nn3">Using R and SWIG</a>
<li><a href="#R_nn4">Precompiling large R files</a>
<li><a href="#R_nn5">General policy</a>
<li><a href="#R_language_conventions">Language conventions</a>
<li><a href="#R_nn6">C++ classes</a>
<li><a href="#R_nn7">Enumerations</a>
</ul>
</div>
<!-- INDEX -->
<p>
R is a GPL'ed open source statistical and plotting environment.
Information about R can be found at <a
href="http://www.r-project.org/">www.r-project.org</a>.
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++.
</p>
<H2><a name="R_nn2">37.1 Bugs</a></H2>
<p>
Currently the following features are not implemented or broken:
</p>
<ul>
<li>Garbage collection of created objects
<li>C Array wrappings
</ul>
<H2><a name="R_nn3">37.2 Using R and SWIG</a></H2>
<p>
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
</p>
<div class="shell">
<pre>
swig -r example.i
R CMD SHLIB example_wrap.c example.c
</pre>
</div>
<p>
The corresponding options for C++ mode are
</p>
<div class="shell">
<pre>
swig -c++ -r -o example_wrap.cpp example.i
R CMD SHLIB example_wrap.cpp example.cpp
</pre>
</div>
<p>
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:
</p>
<div class="shell">
<pre>
swig -c++ -r -o example_wrap.cpp example.i
R CMD SHLIB -o example.so example_wrap.cpp example.cpp
</pre>
</div>
<p>
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:
</p>
<div class="shell">
<pre>
swig -c++ -r -o example_wrap.cpp example.i
PKG_LIBS="example.cxx" R CMD SHLIB -o example example_wrap.cpp
</pre>
</div>
<p>
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
</p>
<div class="shell">
<pre>
dyn.load(paste("example", .Platform$dynlib.ext, sep=""))
source("example.R")
cacheMetaData(1)
</pre>
</div>
The cacheMetaData(1) will cause R to refresh its object tables.
Without it, inheritance of wrapped objects may fail.
<p>
These two files can be loaded in any order
</p>
<p>
If you are compiling code yourself (not using R itself), there are a few things to watch out for:
</p>
<ul>
<li>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
<li>If you do not set the output file name appropriately, you might see errors like
<div class="shell">
<pre>
> 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"
</pre>
</div>
<li>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
</ul>
<H2><a name="R_nn4">37.3 Precompiling large R files</a></H2>
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
<pre>
source('BigFile.R')
save(list=ls(all=TRUE), file="BigFile.RData", compress=TRUE)
q(save="no")
</pre>
This will generate a compiled R file called BigFile.RData that
will save a large amount of loading time.
<H2><a name="R_nn5">37.4 General policy</a></H2>
<p>
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.
</p>
<H2><a name="R_language_conventions">37.5 Language conventions</a></H2>
<p>
getitem and setitem use C++ conventions (i.e. zero based indices). [<-
and [ are overloaded to allow for R syntax (one based indices and
slices)
</p>
<H2><a name="R_nn6">37.6 C++ classes</a></H2>
<p>
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.
</p>
<H2><a name="R_nn7">37.7 Enumerations</a></H2>
<p>
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.
</p>
</body>
</html>
|