rice2 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +23 -0
  3. data/Doxyfile +2268 -0
  4. data/Makefile.am +26 -0
  5. data/Makefile.in +929 -0
  6. data/README.md +1054 -0
  7. data/README.mingw +8 -0
  8. data/Rakefile +24 -0
  9. data/aclocal.m4 +1090 -0
  10. data/bootstrap +8 -0
  11. data/config.guess +1667 -0
  12. data/config.sub +1793 -0
  13. data/configure +8209 -0
  14. data/configure.ac +55 -0
  15. data/depcomp +791 -0
  16. data/doxygen.ac +314 -0
  17. data/doxygen.am +186 -0
  18. data/extconf.rb +66 -0
  19. data/install-sh +529 -0
  20. data/missing +215 -0
  21. data/post-autoconf.rb +22 -0
  22. data/post-automake.rb +28 -0
  23. data/rice/Address_Registration_Guard.cpp +22 -0
  24. data/rice/Address_Registration_Guard.hpp +7 -0
  25. data/rice/Address_Registration_Guard.ipp +37 -0
  26. data/rice/Address_Registration_Guard_defn.hpp +75 -0
  27. data/rice/Arg.hpp +8 -0
  28. data/rice/Arg_impl.hpp +129 -0
  29. data/rice/Arg_operators.cpp +21 -0
  30. data/rice/Arg_operators.hpp +19 -0
  31. data/rice/Array.hpp +214 -0
  32. data/rice/Array.ipp +256 -0
  33. data/rice/Builtin_Object.hpp +8 -0
  34. data/rice/Builtin_Object.ipp +50 -0
  35. data/rice/Builtin_Object_defn.hpp +50 -0
  36. data/rice/Class.cpp +57 -0
  37. data/rice/Class.hpp +8 -0
  38. data/rice/Class.ipp +6 -0
  39. data/rice/Class_defn.hpp +83 -0
  40. data/rice/Constructor.hpp +47 -0
  41. data/rice/Data_Object.hpp +8 -0
  42. data/rice/Data_Object.ipp +133 -0
  43. data/rice/Data_Object_defn.hpp +138 -0
  44. data/rice/Data_Type.cpp +54 -0
  45. data/rice/Data_Type.hpp +8 -0
  46. data/rice/Data_Type.ipp +365 -0
  47. data/rice/Data_Type_defn.hpp +261 -0
  48. data/rice/Data_Type_fwd.hpp +12 -0
  49. data/rice/Director.cpp +13 -0
  50. data/rice/Director.hpp +39 -0
  51. data/rice/Enum.hpp +117 -0
  52. data/rice/Enum.ipp +246 -0
  53. data/rice/Exception.cpp +59 -0
  54. data/rice/Exception.hpp +13 -0
  55. data/rice/Exception_Base.hpp +8 -0
  56. data/rice/Exception_Base.ipp +13 -0
  57. data/rice/Exception_Base_defn.hpp +27 -0
  58. data/rice/Exception_defn.hpp +69 -0
  59. data/rice/Hash.hpp +227 -0
  60. data/rice/Hash.ipp +329 -0
  61. data/rice/Identifier.cpp +8 -0
  62. data/rice/Identifier.hpp +50 -0
  63. data/rice/Identifier.ipp +33 -0
  64. data/rice/Jump_Tag.hpp +24 -0
  65. data/rice/Makefile.am +122 -0
  66. data/rice/Makefile.in +885 -0
  67. data/rice/Module.cpp +84 -0
  68. data/rice/Module.hpp +8 -0
  69. data/rice/Module.ipp +6 -0
  70. data/rice/Module_defn.hpp +88 -0
  71. data/rice/Module_impl.hpp +281 -0
  72. data/rice/Module_impl.ipp +345 -0
  73. data/rice/Object.cpp +169 -0
  74. data/rice/Object.hpp +8 -0
  75. data/rice/Object.ipp +33 -0
  76. data/rice/Object_defn.hpp +214 -0
  77. data/rice/Require_Guard.hpp +21 -0
  78. data/rice/String.cpp +94 -0
  79. data/rice/String.hpp +91 -0
  80. data/rice/Struct.cpp +117 -0
  81. data/rice/Struct.hpp +162 -0
  82. data/rice/Struct.ipp +26 -0
  83. data/rice/Symbol.cpp +25 -0
  84. data/rice/Symbol.hpp +66 -0
  85. data/rice/Symbol.ipp +44 -0
  86. data/rice/config.hpp +47 -0
  87. data/rice/config.hpp.in +46 -0
  88. data/rice/detail/Arguments.hpp +118 -0
  89. data/rice/detail/Auto_Function_Wrapper.hpp +898 -0
  90. data/rice/detail/Auto_Function_Wrapper.ipp +3694 -0
  91. data/rice/detail/Auto_Member_Function_Wrapper.hpp +897 -0
  92. data/rice/detail/Auto_Member_Function_Wrapper.ipp +2774 -0
  93. data/rice/detail/Caster.hpp +103 -0
  94. data/rice/detail/Exception_Handler.hpp +8 -0
  95. data/rice/detail/Exception_Handler.ipp +68 -0
  96. data/rice/detail/Exception_Handler_defn.hpp +96 -0
  97. data/rice/detail/Iterator.hpp +93 -0
  98. data/rice/detail/Not_Copyable.hpp +25 -0
  99. data/rice/detail/Wrapped_Function.hpp +33 -0
  100. data/rice/detail/cfp.hpp +24 -0
  101. data/rice/detail/cfp.ipp +51 -0
  102. data/rice/detail/check_ruby_type.cpp +27 -0
  103. data/rice/detail/check_ruby_type.hpp +23 -0
  104. data/rice/detail/creation_funcs.hpp +37 -0
  105. data/rice/detail/creation_funcs.ipp +36 -0
  106. data/rice/detail/default_allocation_func.hpp +23 -0
  107. data/rice/detail/default_allocation_func.ipp +11 -0
  108. data/rice/detail/define_method_and_auto_wrap.hpp +31 -0
  109. data/rice/detail/define_method_and_auto_wrap.ipp +30 -0
  110. data/rice/detail/demangle.cpp +56 -0
  111. data/rice/detail/demangle.hpp +19 -0
  112. data/rice/detail/env.hpp +11 -0
  113. data/rice/detail/from_ruby.hpp +43 -0
  114. data/rice/detail/from_ruby.ipp +60 -0
  115. data/rice/detail/method_data.cpp +92 -0
  116. data/rice/detail/method_data.hpp +21 -0
  117. data/rice/detail/node.hpp +13 -0
  118. data/rice/detail/protect.cpp +29 -0
  119. data/rice/detail/protect.hpp +34 -0
  120. data/rice/detail/ruby.hpp +74 -0
  121. data/rice/detail/ruby_version_code.hpp +6 -0
  122. data/rice/detail/ruby_version_code.hpp.in +6 -0
  123. data/rice/detail/st.hpp +22 -0
  124. data/rice/detail/to_ruby.hpp +22 -0
  125. data/rice/detail/to_ruby.ipp +36 -0
  126. data/rice/detail/traits.hpp +43 -0
  127. data/rice/detail/win32.hpp +16 -0
  128. data/rice/detail/wrap_function.hpp +66 -0
  129. data/rice/global_function.hpp +33 -0
  130. data/rice/global_function.ipp +22 -0
  131. data/rice/protect.hpp +38 -0
  132. data/rice/protect.ipp +1134 -0
  133. data/rice/ruby_mark.hpp +13 -0
  134. data/rice/ruby_try_catch.hpp +86 -0
  135. data/rice/rubypp.rb +97 -0
  136. data/rice/to_from_ruby.hpp +8 -0
  137. data/rice/to_from_ruby.ipp +418 -0
  138. data/rice/to_from_ruby_defn.hpp +70 -0
  139. data/ruby.ac +135 -0
  140. data/ruby/Makefile.am +1 -0
  141. data/ruby/Makefile.in +628 -0
  142. data/ruby/lib/Makefile.am +3 -0
  143. data/ruby/lib/Makefile.in +506 -0
  144. data/ruby/lib/mkmf-rice.rb.in +217 -0
  145. data/ruby/lib/version.rb +3 -0
  146. data/sample/Makefile.am +47 -0
  147. data/sample/Makefile.in +489 -0
  148. data/sample/enum/extconf.rb +3 -0
  149. data/sample/enum/sample_enum.cpp +54 -0
  150. data/sample/enum/test.rb +8 -0
  151. data/sample/inheritance/animals.cpp +98 -0
  152. data/sample/inheritance/extconf.rb +3 -0
  153. data/sample/inheritance/test.rb +7 -0
  154. data/sample/map/extconf.rb +3 -0
  155. data/sample/map/map.cpp +81 -0
  156. data/sample/map/test.rb +7 -0
  157. data/test/Makefile.am +72 -0
  158. data/test/Makefile.in +1213 -0
  159. data/test/ext/Makefile.am +41 -0
  160. data/test/ext/Makefile.in +483 -0
  161. data/test/ext/t1/Foo.hpp +10 -0
  162. data/test/ext/t1/extconf.rb +2 -0
  163. data/test/ext/t1/t1.cpp +15 -0
  164. data/test/ext/t2/extconf.rb +2 -0
  165. data/test/ext/t2/t2.cpp +11 -0
  166. data/test/test_Address_Registration_Guard.cpp +43 -0
  167. data/test/test_Array.cpp +248 -0
  168. data/test/test_Builtin_Object.cpp +71 -0
  169. data/test/test_Class.cpp +496 -0
  170. data/test/test_Constructor.cpp +128 -0
  171. data/test/test_Data_Object.cpp +275 -0
  172. data/test/test_Data_Type.cpp +348 -0
  173. data/test/test_Director.cpp +308 -0
  174. data/test/test_Enum.cpp +215 -0
  175. data/test/test_Exception.cpp +47 -0
  176. data/test/test_Hash.cpp +212 -0
  177. data/test/test_Identifier.cpp +70 -0
  178. data/test/test_Jump_Tag.cpp +17 -0
  179. data/test/test_Memory_Management.cpp +50 -0
  180. data/test/test_Module.cpp +497 -0
  181. data/test/test_Object.cpp +159 -0
  182. data/test/test_String.cpp +107 -0
  183. data/test/test_Struct.cpp +205 -0
  184. data/test/test_Symbol.cpp +63 -0
  185. data/test/test_To_From_Ruby.cpp +428 -0
  186. data/test/test_global_functions.cpp +114 -0
  187. data/test/test_rice.rb +41 -0
  188. data/test/unittest.cpp +136 -0
  189. data/test/unittest.hpp +294 -0
  190. metadata +297 -0
@@ -0,0 +1,1054 @@
1
+ # Rice - Ruby Interface for C++ Extensions {#mainpage}
2
+
3
+ # Introduction {#intro}
4
+
5
+ Rice is a C++ interface to Ruby's C API. It provides a type-safe and
6
+ exception-safe interface in order to make embedding Ruby and writing
7
+ Ruby extensions with C++ easier. It is similar to Boost.Python in many
8
+ ways, but also attempts to provide an object-oriented interface to all
9
+ of the Ruby C API.
10
+
11
+ What Rice gives you:
12
+ - A simple C++-based syntax for wrapping and defining classes
13
+ - Automatic conversion of exceptions between C++ and Ruby
14
+ - Smart pointers for handling garbage collection
15
+ - Wrappers for most builtin types to simplify calling code
16
+
17
+ # Project Details {#project}
18
+
19
+ The source is hosted on github: http://github.com/jasonroelofs/rice
20
+
21
+ Bug tracking: http://github.com/jasonroelofs/rice/issues
22
+
23
+ API documentation: http://jasonroelofs.github.io/rice
24
+
25
+ # Installation {#installation}
26
+
27
+ ~~~
28
+ gem install rice
29
+ ~~~
30
+
31
+ Building it locally from a clone of the repository is as follows:
32
+
33
+ ~~~
34
+ ./bootstrap
35
+ ruby extconf.rb
36
+ make
37
+ ~~~
38
+
39
+ Rice is known to work on *nix and OSX. Windows is not currently
40
+ supported.
41
+
42
+ Rice requires a C++ compiler with support for C++14 or later.
43
+
44
+ # Tutorial {#tutorial}
45
+
46
+ ## Getting started {#getting_started}
47
+
48
+ Writing an extension with Rice is very similar to writing an extension
49
+ with the C API.
50
+
51
+ The first step is to create an extconf.rb file:
52
+
53
+ ~~~{.cpp}
54
+ require 'mkmf-rice'
55
+ create_makefile('test')
56
+ ~~~
57
+
58
+ Note that we use `mkmf-rice` instead of `mkmf`. This will ensure that the
59
+ extension will be linked with standard C++ library along with the Rice
60
+ library, and allow access to the Rice header files.
61
+
62
+ Next we create our extension and save it to test.cpp:
63
+
64
+ ~~~{.cpp}
65
+ extern "C"
66
+ void Init_test()
67
+ {
68
+ }
69
+ ~~~
70
+
71
+ Note the extern "C" line above. This tells the compiler that the
72
+ function `Init_test` should have C linkage and calling convention. This
73
+ turns off name mangling so that the Ruby interpreter will be able to
74
+ find the function (remember that Ruby is written in C, not C++).
75
+
76
+ So far we haven't put anything into the extension, so it isn't
77
+ particularly useful. The next step is to define a class so we can add
78
+ methods to it.
79
+
80
+
81
+ ## Defining clases {#classes}
82
+
83
+ Defining a class in Rice is easy:
84
+
85
+ ~~~{.cpp}
86
+ #include "rice/Class.hpp"
87
+
88
+ using namespace Rice;
89
+
90
+ extern "C"
91
+ void Init_test()
92
+ {
93
+ Class rb_cTest = define_class("Test");
94
+ }
95
+ ~~~
96
+
97
+ This will create a class called `Test` that inherits from `Object`. If we
98
+ wanted to inherit from a different class, we could easily do so:
99
+
100
+ ~~~{.cpp}
101
+ #include "rice/Class.hpp"
102
+
103
+ using namespace Rice;
104
+
105
+ extern "C"
106
+ void Init_test()
107
+ {
108
+ Class rb_cMySocket = define_class("MySocket", rb_cIO);
109
+ }
110
+ ~~~
111
+
112
+ Note the prefix rb_c on the name of the class. This is a convention
113
+ that the Ruby interpreter and many extensions tend to use. It signifies
114
+ that this is a class and not some other type of object. Some other
115
+ naming conventions that are commonly used:
116
+
117
+ - rb_c variable name prefix for a Class
118
+ - rb_m variable name prefix for a Module
119
+ - rb_e variable name prefix for an Exception type
120
+ - rb_ function prefix for a function in the Ruby C API
121
+ - rb_f_ function prefix to differentiate between an API function that
122
+ takes Ruby objects as arguments and one that takes C argument types
123
+ - rb_*_s_ indicates the function is a singleton function
124
+ - *_m suffix to indicate the function takes variable number of
125
+ arguments
126
+
127
+
128
+ Also note that we don't include "ruby.h" directly. Rice has a wrapper
129
+ for ruby.h that handles some compatibility issues across platforms and
130
+ Ruby versions. Always include Rice headers before including anything
131
+ that might include "ruby.h".
132
+
133
+ ## Defining methods {#methods}
134
+
135
+ Now let's add a method to our class:
136
+
137
+ ~~~{.cpp}
138
+ #include "rice/Class.hpp"
139
+ #include "rice/String.hpp"
140
+
141
+ using namespace Rice;
142
+
143
+ Object test_hello(Object /* self */)
144
+ {
145
+ String str("hello, world");
146
+ return str;
147
+ }
148
+
149
+ extern "C"
150
+ void Init_test()
151
+ {
152
+ Class rb_cTest =
153
+ define_class("Test")
154
+ .define_method("hello", &test_hello);
155
+ }
156
+ ~~~
157
+
158
+ Here we add a method `%Test#hello` that simply returns the string
159
+ "Hello, World". The method takes self as an implicit parameter, but
160
+ isn't used, so we comment it out to prevent a compiler warning.
161
+
162
+ We could also add an `#initialize` method to our class:
163
+
164
+ ~~~{.cpp}
165
+ #include "rice/Class.hpp"
166
+ #include "rice/String.hpp"
167
+
168
+ using namespace Rice;
169
+
170
+ Object test_initialize(Object self)
171
+ {
172
+ self.iv_set("@foo", 42);
173
+ }
174
+
175
+ Object test_hello(Object /* self */)
176
+ {
177
+ String str("hello, world");
178
+ return str;
179
+ }
180
+
181
+ extern "C"
182
+ void Init_test()
183
+ {
184
+ Class rb_cTest =
185
+ define_class("Test")
186
+ .define_method("initialize", &test_initialize)
187
+ .define_method("hello", &test_hello);
188
+ }
189
+ ~~~
190
+
191
+ The `initialize` method sets an instance variable `@foo` to the value 42.
192
+ The number is automatically converted to a `Fixnum` before doing the
193
+ assignment.
194
+
195
+ Note that we're chaining calls on the `Class` object. Most member
196
+ functions in `Module` and `Class` return a reference to self, so we can
197
+ chain as many calls as we want to define as many methods as we want.
198
+
199
+
200
+ ## Wrapping C++ Types {#data_types}
201
+
202
+ It's useful to be able to define Ruby classes in a C++ style rather than
203
+ using the Ruby API directly, but the real power Rice is in wrapping
204
+ already-defined C++ types.
205
+
206
+ Let's assume we have the following C++ class that we want to wrap:
207
+
208
+ ~~~{.cpp}
209
+ class Test
210
+ {
211
+ public:
212
+ Test();
213
+ std::string hello();
214
+ };
215
+ ~~~
216
+
217
+ This is a C++ version of the Ruby class we just created in the previous
218
+ section. To wrap it:
219
+
220
+ ~~~{.cpp}
221
+ #include "rice/Data_Type.hpp"
222
+ #include "rice/Constructor.hpp"
223
+
224
+ using namespace Rice;
225
+
226
+ extern "C"
227
+ void Init_test()
228
+ {
229
+ Data_Type<Test> rb_cTest =
230
+ define_class<Test>("Test")
231
+ .define_constructor(Constructor<Test>())
232
+ .define_method("hello", &Test::hello);
233
+ }
234
+ ~~~
235
+
236
+ This example is similar to the one before, but we use `Data_Type<>`
237
+ instead of `Class` and the template version of define_class() instead of
238
+ the non-template version. This creates a binding in the Rice library
239
+ between the Ruby class `Test` and the C++ class Test such that Rice passes
240
+ member function pointers to `define_method()`.
241
+
242
+ It is possible to write the conversion functions ourself (as we'll see
243
+ below), but Rice does all the dirty work for us.
244
+
245
+
246
+ ## Type conversions {#conversions}
247
+
248
+ Let's look again at our example class:
249
+
250
+ ~~~{.cpp}
251
+ class Test
252
+ {
253
+ public:
254
+ Test();
255
+ std::string hello();
256
+ };
257
+ ~~~
258
+
259
+ When we wrote our class, we never wrote a single line of code to convert
260
+ the `std::string` returned by `hello()` into a Ruby type. Neverthless, the
261
+ conversion works, and when we write:
262
+
263
+ ~~~{.cpp}
264
+ test = Test.new
265
+ puts test.hello
266
+ ~~~
267
+
268
+ We get the expected result.
269
+
270
+ Rice has two template conversion functions to convert between C++ and
271
+ Ruby types:
272
+
273
+ ~~~{.cpp}
274
+ template<typename T>
275
+ T from_ruby(Object x);
276
+
277
+ template<typename T>
278
+ Object to_ruby(T const & x);
279
+ ~~~
280
+
281
+ Rice has included by default specializations for many of the builtin
282
+ types. To define your own conversion, you can write a specialization:
283
+
284
+ ~~~{.cpp}
285
+ template<>
286
+ Foo from_ruby<Foo>(Object x)
287
+ {
288
+ // ...
289
+ }
290
+
291
+ template<>
292
+ Object to_ruby<Foo>(Foo const & x)
293
+ {
294
+ // ...
295
+ }
296
+ ~~~
297
+
298
+ The implementation of these functions would, of course, depend on the
299
+ implementation of `Foo`.
300
+
301
+
302
+ ## Conversions for wrapped C++ types {#data_conversions}
303
+
304
+ Take another look at the wrapper we wrote for the `Test` class:
305
+
306
+ ~~~{.cpp}
307
+ extern "C"
308
+ void Init_test()
309
+ {
310
+ Data_Type<Test> rb_cTest =
311
+ define_class<Test>("Test")
312
+ .define_constructor(Constructor<Test>())
313
+ .define_method("hello", &Test::hello);
314
+ }
315
+ ~~~
316
+
317
+ When we called `define_class<Test>`, it created a Class for us and
318
+ automatically registered the new Class with the type system, so that the
319
+ calls:
320
+
321
+ ~~~{.cpp}
322
+ Data_Object<Foo> obj(new Foo);
323
+ Foo * f = from_ruby<Foo *>(obj);
324
+ Foo const * f = from_ruby<Foo const *>(obj);
325
+ ~~~
326
+
327
+ works as expected.
328
+
329
+ The `Data_Object` class is a wrapper for the `Data_Wrap_Struct` and the
330
+ `Data_Get_Struct` macros in C extensions. It can be used to wrap or
331
+ unwrap any class that has been assigned to a `Data_Type`. It inherits
332
+ from `Object`, so any member functions we can call on an `Object` we can
333
+ also call on a `Data_Object`:
334
+
335
+ ~~~{.cpp}
336
+ Object object_id = obj.call("object_id");
337
+ std::cout << object_id << std::endl;
338
+ ~~~
339
+
340
+ The `Data_Object` class can be used to wrap a newly-created object:
341
+
342
+ ~~~{.cpp}
343
+ Data_Object<Foo> foo(new Foo);
344
+ ~~~
345
+
346
+ or to unwrap an already-created object:
347
+
348
+ ~~~{.cpp}
349
+ VALUE obj = ...;
350
+ Data_Object<Foo> foo(obj);
351
+ ~~~
352
+
353
+ A `Data_Object` functions like a smart pointer:
354
+
355
+ ~~~{.cpp}
356
+ Data_Object<Foo> foo(obj);
357
+ foo->foo();
358
+ std::cout << *foo << std::endl;
359
+ ~~~
360
+
361
+ Like a `VALUE` or an `Object`, data stored in a `Data_Object` will be marked
362
+ by the garbage collector as long as the `Data_Object` is on the stack.
363
+
364
+
365
+ ## Exceptions {#exception}
366
+
367
+ Suppose we added a member function to our example class that throws an
368
+ exception:
369
+
370
+ ~~~{.cpp}
371
+ class MyException
372
+ : public std::exception
373
+ {
374
+ };
375
+
376
+ class Test
377
+ {
378
+ public:
379
+ Test();
380
+ std::string hello();
381
+ void error();
382
+ };
383
+ ~~~
384
+
385
+ If we were to wrap this function:
386
+
387
+ ~~~{.cpp}
388
+ extern "C"
389
+ void Init_test()
390
+ {
391
+ Data_Type<Test> rb_cTest =
392
+ define_class<Test>("Test")
393
+ .define_constructor(Constructor<Test>())
394
+ .define_method("hello", &Test::hello)
395
+ .define_method("error", &Test::error);
396
+ }
397
+ ~~~
398
+
399
+ and call it from inside Ruby:
400
+
401
+ ~~~{.cpp}
402
+ test = Test.new
403
+ test.error()
404
+ ~~~
405
+
406
+ we would get an exception. Rice will automatically convert any
407
+ C++ exception it catches into a Ruby exception. But what if we wanted
408
+ to use a custom error message when we convert the exception, or what if
409
+ we wanted to convert to a different type of exception? We can write
410
+ this:
411
+
412
+ ~~~{.cpp}
413
+ extern "C"
414
+ void Init_test()
415
+ {
416
+ Data_Type<Test> rb_cTest =
417
+ define_class<Test>("Test")
418
+ .add_handler<MyException>(handle_my_exception)
419
+ .define_constructor(Constructor<Test>())
420
+ .define_method("hello", &Test::hello)
421
+ .define_method("error", &Test::error);
422
+ }
423
+ ~~~
424
+
425
+ The `handle_my_exception` function need only rethrow the exception as a
426
+ `Rice::Exception`:
427
+
428
+ ~~~{.cpp}
429
+ void handle_my_exception(MyException const & ex)
430
+ {
431
+ throw Exception(rb_eRuntimeError, "Goodnight, moon");
432
+ }
433
+ ~~~
434
+
435
+ And what if we want to call Ruby code from C++? These exceptions are
436
+ also converted:
437
+
438
+ ~~~{.cpp}
439
+ Object o;
440
+ o.call("some_function_that_raises", 42);
441
+
442
+ protect(rb_raise, rb_eRuntimeError, "some exception msg");
443
+ ~~~
444
+
445
+ Internally whenever Rice catches a C++ or a Ruby exception, it converts
446
+ it to an `Exception` object. This object will later be re-raised as a
447
+ Ruby exception when control is returned to the Ruby VM.
448
+
449
+ Rice uses a similar class called `Jump_Tag` to handle symbols thrown by
450
+ Ruby's `throw`/`catch` or other non-local jumps from inside the Ruby VM.
451
+
452
+
453
+ ## Builtin Types {#builtin}
454
+
455
+ You've seen this example:
456
+
457
+ ~~~{.cpp}
458
+ Object object_id = obj.call("object_id");
459
+ std::cout << object_id << std::endl;
460
+ ~~~
461
+
462
+ Rice mimics the Ruby class hierarchy as closely as it can.
463
+ In fact, the above code also works for Classes:
464
+
465
+ ~~~{.cpp}
466
+ Class rb_cTest = define_class<Test>("Test");
467
+ Object object_id = rb_cTest.call("object_id");
468
+ std::cout << object_id << std::endl;
469
+ ~~~
470
+
471
+ Rice provides builtin wrappers for many builtin Ruby types, including:
472
+
473
+ - Object
474
+ - Module
475
+ - Class
476
+ - String
477
+ - Array
478
+ - Hash
479
+ - Struct
480
+ - Symbol
481
+ - Exception
482
+
483
+ The `Array` and `Hash` types can even be iterated over the same way one
484
+ would iterate over an STL container:
485
+
486
+ ~~~{.cpp}
487
+ Array a;
488
+ a.push(to_ruby(42));
489
+ a.push(to_ruby(43));
490
+ a.push(to_ruby(44));
491
+ Array::iterator it = a.begin();
492
+ Array::iterator end = a.end();
493
+ for(; it != end; ++it)
494
+ {
495
+ std::cout << *it << std::endl;
496
+ }
497
+ ~~~
498
+
499
+ STL algorithms should also work as expected on `Array` and `Hash` containers.
500
+
501
+
502
+ ## Inheritance {#inheritance}
503
+
504
+ Inheritance is a tricky problem to solve in extensions. This is because
505
+ wrapper functions for base classes typically don't know how to accept
506
+ pointers to derived classes. It is possible to write this logic, but
507
+ the code is nontrivial.
508
+
509
+ Forunately Rice handles this gracefully:
510
+
511
+ ~~~{.cpp}
512
+ class Base
513
+ {
514
+ public:
515
+ virtual void foo();
516
+ };
517
+
518
+ class Derived
519
+ : public Base
520
+ {
521
+ };
522
+
523
+ extern "C"
524
+ void Init_test()
525
+ {
526
+ Data_Type<Base> rb_cBase =
527
+ define_class<Base>("Base")
528
+ .define_method("foo", &Base::foo);
529
+ Data_Type<Derived> rb_cDerived =
530
+ define_class<Derived, Base>("Derived");
531
+ }
532
+ ~~~
533
+
534
+ The second template parameter to define_class indicates that `Derived`
535
+ inherits from `Base`.
536
+
537
+ Rice does not support multiple inheritance.
538
+
539
+
540
+ ## Overloaded functions {#overloading}
541
+
542
+ If you try to create a member function pointer to an overloaded
543
+ function, you will get an error. So how do we wrap classes that have
544
+ overloaded functions?
545
+
546
+ Consider a class that uses this idiom for accessors:
547
+
548
+ ~~~{.cpp}
549
+ class Container
550
+ {
551
+ size_t capacity(); // Get the capacity
552
+ void capacity(size_t cap); // Set the capacity
553
+ };
554
+ ~~~
555
+
556
+ We can wrap this class by using `typedef`s:
557
+
558
+ ~~~{.cpp}
559
+ extern "C"
560
+ void Init_Container()
561
+ {
562
+ typedef size_t (Container::*get_capacity)();
563
+ typedef void (Container::*set_capacity)(size_t);
564
+
565
+ Data_Type<Container> rb_cContainer =
566
+ define_class<Container>("Container")
567
+ .define_method("capacity", get_capacity(&Container::capacity))
568
+ .define_method("capacity=", set_capacity(&Container::capacity))
569
+ }
570
+ ~~~
571
+
572
+
573
+ ## User-defined type conversions {#user_defined_conversions}
574
+
575
+ Rice provides default conversions for many built-in types. Sometimes,
576
+ however, the default conversion is not what is expected. For
577
+ example, consider a function:
578
+
579
+ ~~~{.cpp}
580
+ void foo(char * x);
581
+ ~~~
582
+
583
+ Is `x` a pointer to a single character or a pointer to the first character
584
+ of a null-terminated string or a pointer to the first character of an
585
+ array of char?
586
+
587
+ Because the second case is the most common use case (a pointer to the
588
+ first character of a C string), Rice provides a default conversion that
589
+ treats a `char *` as a C string. But suppose the above function takes a
590
+ pointer to a char instead?
591
+
592
+ If we write this:
593
+
594
+ ~~~{.cpp}
595
+ extern "C"
596
+ void Init_test()
597
+ {
598
+ define_global_function("foo", &foo);
599
+ }
600
+ ~~~
601
+
602
+ It will likely have the wrong behavior.
603
+
604
+ To avoid this problem, it is necessary to write a wrapper function:
605
+
606
+ ~~~{.cpp}
607
+ Object wrap_foo(Object o)
608
+ {
609
+ char c = from_ruby<char>(o);
610
+ foo(&c);
611
+ return to_ruby(c);
612
+ }
613
+
614
+ extern "C"
615
+ void Init_test()
616
+ {
617
+ define_global_function("foo", &wrap_foo);
618
+ }
619
+ ~~~
620
+
621
+ Note that the out parameter is returned from `wrap_foo`, as Ruby does not
622
+ have pass-by-variable-reference (it uses pass-by-object-reference).
623
+
624
+
625
+ ## Default Arguments {#default_arguments}
626
+
627
+ Going back to our initial C++ class example, lets say that `hello()` now
628
+ takes more arguments, one of which has a default value:
629
+
630
+ ~~~{.cpp}
631
+ class Test
632
+ {
633
+ public:
634
+ Test();
635
+ std::string hello(std::string first, std::string second = "world");
636
+ };
637
+ ~~~
638
+
639
+ As default parameter information is not available through templates,
640
+ it is necessary to define this in Rice explicitly using `Rice::Arg`:
641
+
642
+ ~~~{.cpp}
643
+ #include "rice/Data_Type.hpp"
644
+ #include "rice/Constructor.hpp"
645
+
646
+ using namespace Rice;
647
+
648
+ extern "C"
649
+ void Init_test()
650
+ {
651
+ Data_Type<Test> rb_cTest =
652
+ define_class<Test>("Test")
653
+ .define_constructor(Constructor<Test>())
654
+ .define_method("hello",
655
+ &Test::hello,
656
+ (Arg("hello"), Arg("second") = "world")
657
+ );
658
+ }
659
+ ~~~
660
+
661
+ The syntax here is simply `Arg(nameOfParameter)[ = defaultValue]`. The name of the
662
+ parameter is not important here (a readability tool), but the value set via `operator=`
663
+ must match the type of the parameter. As such it may be necessary to
664
+ explicitly cast the default value.
665
+
666
+ ~~~{.cpp}
667
+ .define_method("hello",
668
+ &Test::hello,
669
+ (Arg("hello"), Arg("second") = (std::string)"world")
670
+ );
671
+ ~~~
672
+
673
+ These `Rice::Arg` objects must be in the correct order and must be
674
+ surrounded with parentheses if more than one exists.
675
+
676
+ Now, Ruby will now know about the default arguments, and this wrapper
677
+ can be used as expected:
678
+
679
+ ~~~{.cpp}
680
+ t = Test.new
681
+ t.hello("hello")
682
+ t.hello("goodnight", "moon")
683
+ ~~~
684
+
685
+ This also works with Constructors:
686
+
687
+ ~~~{.cpp}
688
+ .define_constructor(Constructor<SomeClass, int, int>(),
689
+ ( Arg("arg1") = 1, Arg("otherArg") = 12 );
690
+ ~~~
691
+
692
+ ## Director {#director}
693
+
694
+ As polymorphism is the most important tennant of Object Oriented Programming,
695
+ it is important that Rice supports polymorphic calls travelling between C++
696
+ and Ruby seemlessly. Super calls from Ruby subclasses back into C++ already work,
697
+ but enabling the other direction requires some extra effort. Rice
698
+ supplies the the `Rice::Director` class and
699
+ `Rice::Data_Type::define_director` to expose this functionality.
700
+
701
+ Like `SWIG_Director`, `Rice::Director` is a class that is used to build a proxy class
702
+ to properly send execution up or down the object hierarchy for that class. Take
703
+ the following class:
704
+
705
+ ~~~{.cpp}
706
+ class VirtualBase {
707
+ public:
708
+ VirtualBase();
709
+ virtual int doWork();
710
+ virtual int processWorker() = 0;
711
+ };
712
+ ~~~
713
+
714
+ Due to the abstract nature of this class, it will not work at all with Rice
715
+ in its current form. Any attempt to do so will cause a compilation error due to
716
+ this class not being constructable. Even without the pure virtual function, any
717
+ call to `VirtualBase::doWork` will stop at the C++ level and will not pass down into
718
+ any Ruby subclasses.
719
+
720
+ To properly wrap both of these methods, use a `Rice::Director` subclass as a proxy:
721
+
722
+ ~~~{.cpp}
723
+ #include "rice/Director.hpp"
724
+
725
+ class VirtualBaseProxy : public VirtualBase, public Rice::Director {
726
+ public:
727
+ VirtualBaseProxy(Object self) : Rice::Director(self) { }
728
+
729
+ virtual int doWork() {
730
+ return from_ruby<int>( getSelf().call("do_work") );
731
+ }
732
+
733
+ int default_doWork() {
734
+ return VirtualBase::doWork();
735
+ }
736
+
737
+ virtual int processWorker() {
738
+ return from_ruby<int>( getSelf().call("process_worker") );
739
+ }
740
+
741
+ int default_processWorker() {
742
+ raisePureVirtual();
743
+ }
744
+ };
745
+ ~~~
746
+
747
+ There is a lot going on here, so we'll go through each part.
748
+
749
+ ~~~{.cpp}
750
+ class VirtualBaseProxy : public Virtualbase, public Rice::Director {
751
+ ~~~
752
+
753
+ First, the class needs to subclass both the virtual class in question and `Rice::Director`.
754
+
755
+ ~~~{.cpp}
756
+ public:
757
+ VirtualBaseProxy(Object self) : Rice::Director(self) { }
758
+ ~~~
759
+
760
+ For `Rice::Director` to work its magic, every instance of this class needs to
761
+ have a handle to the Ruby instance. The constructor
762
+ must take a `Rice::Object` as the first argument and pass it up into
763
+ `Rice::Director`. The code here is the minimum required for a `Rice::Director` proxy.
764
+
765
+ ~~~{.cpp}
766
+ virtual int doWork() {
767
+ return from_ruby<int>( getSelf().call("do_work") );
768
+ }
769
+
770
+ int default_doWork() {
771
+ return VirtualBase::doWork();
772
+ }
773
+ ~~~
774
+
775
+ Here the directory proxy overrides the methods for Ruby exposure and
776
+ implements the required actions to pass flow around the hierarchy
777
+ appropriately. The pattern shown here is that the actual override will
778
+ call down into Ruby, handling any type conversions, while a
779
+ `default_methodName` method handles calling up into C++ and will be the
780
+ method wrapped into Rice.
781
+
782
+ The `default_doWork` method will be used as Rice's hookup of calling back up the
783
+ hierarchy (wrapping is below). This method needs to do one of two things: call
784
+ up the class hierarchy, as seen here, or call `raisePureVirtual()` as seen in the
785
+ processWorker example:
786
+
787
+ ~~~{.cpp}
788
+ int default_processWorker() {
789
+ raisePureVirtual();
790
+ }
791
+ ~~~
792
+
793
+ The method `raisePureVirtual()` exists to allow wrapping a pure virtual method into Ruby
794
+ (and ensuring compliation is possible) but making sure any users of this extension are
795
+ informed quickly that there's nothing callable in the C++ side of the library.
796
+
797
+ Once the proxy class is built, it's time to wrap it into Ruby:
798
+
799
+ ~~~{.cpp}
800
+ extern "C"
801
+ void Init_virtual() {
802
+ define_class<VirtualBase>("VirtualBase")
803
+ .define_director<VirtualBaseProxy>()
804
+ .define_constructor(Constructor<VirtualBaseProxy, Rice::Object>())
805
+ .define_method("do_work", &VirtualBaseProxy::default_doWork)
806
+ .define_method("process_worker", &VirtualBaseProxy::default_processWorker);
807
+ }
808
+ ~~~
809
+
810
+ The wrapping is the same as is described earlier in this document. Expose the class
811
+ `VirtualBase`, and register `VirtualBaseProxy` as a director proxy of `VirtualBase` with
812
+ `Rice::Data_Type::define_director`, then `define methods` pointing to the proxy object as necessary.
813
+
814
+ You must use the `Rice::Director` proxy class in the Constructor line, this allows proper
815
+ object construction / destruction of the types in question.
816
+
817
+ ## Implicit Casting {#implicit_cast}
818
+
819
+ There are times when a library exposes classes that, while unrelated, are
820
+ built to be interchangeable across the library. One example of this is found in
821
+ the Open Source 3d rendering engine <a
822
+ href="http://www.ogre3d.org/">OGRE</a>: Ogre::Degree and Ogre::Radian.
823
+ When a given method takes a Radian, you're free to pass in a Degree, and vice versa.
824
+
825
+ Rice cannot automatically figure out if this kind of functionality is
826
+ possible in a given library but it does provide an API for defining
827
+ these relationships: `Rice::define_implicit_cast<From, To>()`.
828
+
829
+ ~~~{.cpp}
830
+ class Degree { ... };
831
+ class Radian { ... };
832
+
833
+ extern "C"
834
+ void Init_implicit() {
835
+ define_class<Degree>()
836
+ ...;
837
+ define_class<Radian>()
838
+ ...;
839
+
840
+ define_implicit_cast<Degree, Radian>();
841
+ define_implicit_cast<Radian, Degree>();
842
+ }
843
+ ~~~
844
+
845
+ Using `Rice::define_implicit_cast` has the following requirements:
846
+
847
+ - The two types must be bound in Rice before defining the cast.
848
+ - The classes must have constructors that take the other type.
849
+ - This feature cannot be used with fundamental types.
850
+
851
+ To see a full example of this feature, please check out
852
+ test/test_Data_Type.cpp.
853
+
854
+ # Motivation {#motivation}
855
+
856
+ There are a number of common problems when writing C or C++ extensions
857
+ for Ruby:
858
+
859
+ - Type safety. It is easy to mix-up integral types such as ID and
860
+ VALUE. Some of the functions in the Ruby API are not consistent with
861
+ which types they take (e.g. rb_const_defined takes an ID and
862
+ rb_mod_remove_const takes a Symbol).
863
+
864
+ - DRY principle. Specifying the number of arguments that each wrapped
865
+ function takes is easy to get wrong. Adding a new argument to the
866
+ function means that the number of arguments passed to rb_define_method
867
+ must also be updated.
868
+
869
+ - Type conversion. There are many different functions to convert data
870
+ to and from ruby types. Many of them have different semantics or
871
+ different forms. For example, to convert a string, one might use the
872
+ StringValue macro, but to convert a fixnum, one might use FIX2INT.
873
+ Unwrapping previously wrapped C data uses yet another form.
874
+
875
+ - Exception safety. It is imperative that C++ exceptions never make
876
+ their way into C code, and it is also imperative that a Ruby exception
877
+ never escape while there are objects on the stack with nontrivial
878
+ destructors. Rules for when it is okay to use which exceptions are
879
+ difficult to get right, especially as code is maintained through time.
880
+
881
+ - Thread safety. Because the Ruby interpreter is not threads-safe,
882
+ the Ruby interpreter must not be run from more than one thread.
883
+ Because of tricks the GC and scheduler play with the C stack, it's not
884
+ enough to ensure that only one thread runs the interpreter at any
885
+ given time; once the interpreter has been run from one thread, it must
886
+ only ever be run from that thread in the future. Additionally,
887
+ because Ruby copies the stack when it switches threads, C++ code must
888
+ be careful not to access objects in one Ruby thread that were created
889
+ on the stack in another Ruby thread.
890
+
891
+ - C-based API. The Ruby API is not always convenient for accessing
892
+ Ruby data structurs such as Hash and Array, especially when writing C++
893
+ code, as the interface for these containers is not consistent with
894
+ standard containers.
895
+
896
+ - Calling convention. Function pointers passed into the Ruby API must
897
+ follow the C calling convention. This means that it is not possible to
898
+ pass a pointer to a template function or static member function (that
899
+ is, it will work on some platforms, but isn't portable).
900
+
901
+ - Inheritance. When wrapping C++ objects, it is easy to store a
902
+ pointer to a derived class, but then methods in the base class must have
903
+ knowledge of the derived class in order to unwrap the object. It is
904
+ possible to always store a pointer to the base class and then
905
+ dynamic_cast the pointer to the derived type when necessary, but this
906
+ can be slow and cumbersome, and it isn't likely to work with multiple
907
+ inheritance. A system that properly handles inheritance for all corner
908
+ cases is nontrivial.
909
+
910
+ - Multiple inheritance. C++ supports true multiple inheritance, but
911
+ the Ruby object model uses single inheritance with mixins. When
912
+ wrapping a library whose public interface uses multiple inheritance,
913
+ care must be taken in constructing the mapping.
914
+
915
+ - GC safety. All live Ruby objects must be marked during the garbage
916
+ collector's mark phase, otherwise they will be prematurely destroyed.
917
+ The general rule is that object references stored on the heap should be
918
+ either registered with rb_gc_register_address or marked by a data
919
+ object's mark function; object references stored on the stack will be
920
+ automatically marked, provided the Ruby interpreter was properly
921
+ initialized at startup.
922
+
923
+ - Callbacks. C implements callbacks via function pointers, while ruby
924
+ typically implements callbacks via procs. Writing an adapter function
925
+ to call the proc is not difficult, but there is much opportunity for
926
+ error (particularly with exception-safety).
927
+
928
+ - Data serialization. By default data objects defined at the C layer
929
+ are not marshalable. The user must explicitly define functions to
930
+ marshal the data member-by-member.
931
+
932
+ Rice addresses these issues in many ways:
933
+
934
+ - Type safety. Rice provides encapsulation for all builtin types,
935
+ such as Object, Identifier, Class, Module, and String. It
936
+ automatically checks the dynamic type of an object before constructing
937
+ an instance of a wrapper.
938
+
939
+ - DRY principle. Rice uses introspection through the use of templates
940
+ and function overloading to automatically determine the number and types
941
+ of arguments to functions. Default arguments must still be handled
942
+ explicitly, however.
943
+
944
+ - Type conversions. Rice provides cast-style to_ruby<> and
945
+ from_ruby<> template functions to simplify explicit type conversions.
946
+ Automatic type conversions for parameters and return values are
947
+ generated for all wrapped functions.
948
+
949
+ - Exception safety. Rice automatically converts common exceptions and
950
+ provides a mechanism for converting user-defined exception types. Rice
951
+ also provides convenience functions for converting exceptions when
952
+ calling back into ruby code.
953
+
954
+ - Thread safety. Rice provides no mechanisms for dealing with thread
955
+ safety. Many common thread safety issues should be alleviated by YARV,
956
+ which supports POSIX threads.
957
+
958
+ - C++-based API. Rice provides an object-oriented C++-style API to
959
+ most common functions in the Ruby C API.
960
+
961
+ - Calling convention. Rice automatically uses C calling convention
962
+ for all function pointers passed into the Ruby API.
963
+
964
+ - Inheritance. Rice provides automatic conversion to the base class
965
+ type when a wrapped member function is called on the base class.
966
+
967
+ - Multiple inheritance. Rice provides no mechanism for multiple
968
+ inheritance. Multiple inheritance can be simulated via mixins, though
969
+ this is not yet as easy as it could be.
970
+
971
+ - GC safety. Rice provides a handful of convenience classes for
972
+ interacting with the garbage collector. There are still basic rules
973
+ which must be followed to ensure that objects get properly destroyed.
974
+
975
+ - Callbacks. Rice provides a handful of convenience classes for
976
+ dealing with callbacks.
977
+
978
+ - Data serialization. Rice provides no mechanism for data
979
+ serialization, but it is likely this may be added in a future release.
980
+
981
+
982
+ # What Rice is Not {#what_not}
983
+
984
+ There are a number projects which server similar functions to Rice. Two
985
+ such popular projects are SWIG and Boost.Python. Rice has some
986
+ distinct features which set it apart from both of these projects.
987
+
988
+ Rice is not trying to replace SWIG. Rice is not a generic wrapper
989
+ interface generator. Rice is a C++ library for interfacing with the
990
+ Ruby C API. This provides a very natural way for C++ programmers to
991
+ wrap their C++ code, without having to learn a new domain-specific
992
+ language. However, there is no reason why SWIG and Rice could not work
993
+ together; a SWIG module could be written to generate Rice code. Such a
994
+ module would combine the portability of SWIG with the maintainability of
995
+ Rice (I have written extensions using both, and I have found Rice
996
+ extensions to be more maintainable when the interface is constantly
997
+ changing. Your mileage may vary).
998
+
999
+ Rice is also not trying to simply be a Ruby version of Boost.Python.
1000
+ Rice does use some of the same template tricks that Boost.Python uses,
1001
+ however there are some important distinctions. First of all,
1002
+ Boost.Python attempts to create a declarative DSL in C++ using
1003
+ templates. Rice is a wrapper around the Ruby C API and attempts to make
1004
+ its interface look like an OO version of the API; this means that class
1005
+ declarations look procedural rather than declarative. Secondly, the
1006
+ Ruby object model is different from the python object model. This is
1007
+ reflected in the interface to Rice; it mimics the Ruby object model at
1008
+ the C++ level. Thirdly, Rice uses Ruby as a code generator; I find this
1009
+ to be much more readable than using the Boost preprocessor library.
1010
+
1011
+
1012
+ # History {#history}
1013
+
1014
+ Rice originated as Excruby, a project to interface with C++-based trading
1015
+ software at Automated Trading Desk in Mount Pleasant, South Carolina.
1016
+ The Ruby bindings for Swig were at the time less mature than they are
1017
+ today, and did not suit the needs of the project.
1018
+
1019
+ Excruby was written not as a wrapper for the Ruby API, but rather as a
1020
+ set of helper functions and classes for interfacing with the Ruby
1021
+ interpreter in an exception-safe manner. Over the course of five years,
1022
+ the project grew into wrappers for pieces of the API, but the original
1023
+ helper functions remained as part of the public interface.
1024
+
1025
+ This created confusion for the users of the library, because there were
1026
+ multiple ways of accomplishing most tasks -- directly through the C API,
1027
+ through a low-level wrapper around the C API, and through a high-level
1028
+ abstraction of the lower-level interfaces.
1029
+
1030
+ Rice was then born in an attempt to clean up the interface. Rice keeps
1031
+ the lower-level wrappers, but as an implementation detail; the public
1032
+ interface is truly a high-level abstraction around the Ruby C API.
1033
+
1034
+
1035
+ # The GC {#gc}
1036
+
1037
+ - Objects are not automatically registered with the garbage collector.
1038
+
1039
+ - If an Object is on the stack, it does not need to be registered with
1040
+ the garbage collector.
1041
+
1042
+ - If an Object is allocated on the heap or if it is a member of an
1043
+ object that might be allocated on the heap, use an
1044
+ Rice::Address_Registration_Guard to register the object with the garbage
1045
+ collector.
1046
+
1047
+ - If a reference counted object is being wrapped, or if another type
1048
+ of smart pointer is wrapped, ensure that only one mechanism is used to
1049
+ destroy the object. In general, the smart pointer manages the
1050
+ allocation of the object, and Ruby should hold only a reference to the
1051
+ smart pointer. When the garbage collector determines that it is time to
1052
+ clean up the object, the smart pointer will be destroyed, decrementing
1053
+ the reference count; when the reference count drops to 0, underlying
1054
+ object will be destroyed.