@@ -17,6 +17,9 @@ <H1><a name="R">34 SWIG and R</a></H1>
17
17
< li > < a href ="#R_nn5 "> General policy</ a >
18
18
< li > < a href ="#R_language_conventions "> Language conventions</ a >
19
19
< li > < a href ="#R_nn6 "> C++ classes</ a >
20
+ < ul >
21
+ < li > < a href ="#R_class_examples "> Examples</ a >
22
+ </ ul >
20
23
< li > < a href ="#R_nn7 "> Enumerations</ a >
21
24
</ ul >
22
25
</ div >
@@ -33,7 +36,11 @@ <H1><a name="R">34 SWIG and R</a></H1>
33
36
< p >
34
37
The R bindings are under active development. They have been used to
35
38
compile and run an R interface to QuantLib running on Mandriva Linux
36
- with gcc. The R bindings also work on Microsoft Windows using Visual C++.
39
+ with gcc. They are also used to create the SimpleITK R package, which
40
+ runs on various linuxes and mac. Swig is used to create all wrapper
41
+ interfaces
42
+ to < a href ="http://http://www.simpleitk.org/ "> SimpleITK</ a > . The R
43
+ bindings also work on Microsoft Windows using Visual C++.
37
44
</ p >
38
45
39
46
< H2 > < a name ="R_nn2 "> 34.1 Bugs</ a > </ H2 >
@@ -44,7 +51,9 @@ <H2><a name="R_nn2">34.1 Bugs</a></H2>
44
51
</ p >
45
52
46
53
< ul >
47
- < li > Garbage collection of created objects
54
+ < li > Garbage collection of some created objects. Finalizers are
55
+ available for wrapped C++ classes and are called by the
56
+ garbage collection system.
48
57
< li > C Array wrappings
49
58
</ ul >
50
59
@@ -158,7 +167,10 @@ <H2><a name="R_nn4">34.3 Precompiling large R files</a></H2>
158
167
will save a large amount of loading time.
159
168
</ p >
160
169
161
-
170
+ < p >
171
+ There is no need to precompile large R files if the SWIG-generated code is being included
172
+ in an R package. The package infrastructure provides this service during package installation.
173
+ </ p >
162
174
163
175
< H2 > < a name ="R_nn5 "> 34.4 General policy</ a > </ H2 >
164
176
@@ -173,7 +185,7 @@ <H2><a name="R_language_conventions">34.5 Language conventions</a></H2>
173
185
174
186
175
187
< p >
176
- getitem and setitem use C++ conventions (i.e. zero based indices). [< -
188
+ getitem and setitem use C++ conventions (i.e. zero based indices). [< -
177
189
and [ are overloaded to allow for R syntax (one based indices and
178
190
slices)
179
191
</ p >
@@ -182,14 +194,117 @@ <H2><a name="R_nn6">34.6 C++ classes</a></H2>
182
194
183
195
184
196
< p >
185
- C++ objects are implemented as external pointer objects with the class
186
- being the mangled name of the class. The C++ classes are encapsulated
187
- as an SEXP with an external pointer type. The class is the mangled
188
- name of the class. The nice thing about R is that is allows you to
189
- keep track of the pointer object which removes the necessity for a lot
190
- of the proxy class baggage you see in other languages.
197
+ Wrapping of C++ classes for R works quite well. R has a special
198
+ type, known as an external reference, that can be used as a pointer
199
+ to arbitary things, including C++ classes. The proxy layers generated
200
+ for other classes are not required.
201
+ </ p >
202
+
203
+ < p >
204
+ SWIG currently creates a custom hierarchy of R classes derived from the
205
+ external reference type and implements
206
+ type checking and function overloading in the R code it generates. In
207
+ the future we hope to utilise the built in R6 class structures.
208
+ </ p >
209
+
210
+ < p >
211
+ The R interface has the following capabilities:
212
+ < ul >
213
+ < li > Destructor methods are registered and called automatically by the R garbage collector.
214
+ < li > A range of std::vector types are converted automatically to R equivalents.
215
+ < li > The $ operator is used for method access.
216
+ < li > Variable accessors are automatically generated and called via the $, [, [[, $<-, [<-, [[<- operators
217
+ </ ul >
191
218
</ p >
192
219
220
+ < H3 > < a name ="R_class_examples "> 34.6.1 Examples</ a > </ H3 >
221
+
222
+
223
+ Consider the following simple example:
224
+
225
+ < div class ="code ">
226
+ < pre >
227
+ class Vehicle {
228
+ private:
229
+ int m_axles;
230
+ public:
231
+ int Axles() {
232
+ return(m_axles);
233
+ }
234
+ bool Available;
235
+
236
+ Vehicle() {
237
+ Available=false;
238
+ m_axles=2;
239
+ }
240
+
241
+ Vehicle(int ax) {
242
+ Available=false;
243
+ m_axles=ax;
244
+ }
245
+ };
246
+ </ pre >
247
+ </ div >
248
+
249
+ The following options are available in R:
250
+
251
+ < div class ="code ">
252
+ < pre >
253
+ v1 <- Vehicle()
254
+ v2 <- Vehicle(4)
255
+ # access members
256
+ v1$Axles()
257
+ [1] 2
258
+ v2$Axles
259
+ [1] 4
260
+ v1$Available
261
+ [1] FALSE
262
+ # Set availabilty
263
+ v1$Available <- TRUE
264
+ v1$Available
265
+ [1] TRUE
266
+ </ pre >
267
+ </ div >
268
+
269
+ < p >
270
+ A useful trick to determine the methods that are available is to
271
+ query the R method definition as follows:
272
+ < p >
273
+
274
+ < div class ="code ">
275
+ < pre >
276
+ # display the methods for the class
277
+ getMethod("$", class(v1))
278
+
279
+ Method Definition:
280
+
281
+ function (x, name)
282
+ {
283
+ accessorFuns = list(Axles = Vehicle_Axles, Available = Vehicle_Available_get)
284
+ vaccessors = c("Available")
285
+ idx = pmatch(name, names(accessorFuns))
286
+ if (is.na(idx))
287
+ return(callNextMethod(x, name))
288
+ f = accessorFuns[[idx]]
289
+ if (is.na(match(name, vaccessors)))
290
+ function(...) {
291
+ f(x, ...)
292
+ }
293
+ else f(x)
294
+ }
295
+ < bytecode: 0x55947ff80f68 >
296
+
297
+ Signatures:
298
+ x
299
+ target "_p_Vehicle"
300
+ defined "_p_Vehicle"
301
+
302
+ </ pre >
303
+ </ div >
304
+ < p >
305
+ The names in the accessorFuns list correspond to class methods while names in the vaccessors section
306
+ correspond to variables that may be modified.
307
+ </ p >
193
308
< H2 > < a name ="R_nn7 "> 34.7 Enumerations</ a > </ H2 >
194
309
195
310
0 commit comments