jameskilton-rice 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (196) hide show
  1. data/COPYING +23 -0
  2. data/Doxyfile +1253 -0
  3. data/Makefile.am +26 -0
  4. data/Makefile.in +749 -0
  5. data/README +879 -0
  6. data/README.mingw +8 -0
  7. data/Rakefile +72 -0
  8. data/aclocal.m4 +891 -0
  9. data/bootstrap +8 -0
  10. data/config.guess +1526 -0
  11. data/config.sub +1658 -0
  12. data/configure +7668 -0
  13. data/configure.ac +52 -0
  14. data/depcomp +589 -0
  15. data/doxygen.ac +314 -0
  16. data/doxygen.am +186 -0
  17. data/extconf.rb +22 -0
  18. data/install-sh +519 -0
  19. data/missing +367 -0
  20. data/post-autoconf.rb +22 -0
  21. data/post-automake.rb +28 -0
  22. data/rice/Address_Registration_Guard.hpp +7 -0
  23. data/rice/Address_Registration_Guard.ipp +34 -0
  24. data/rice/Address_Registration_Guard_defn.hpp +65 -0
  25. data/rice/Allocation_Strategies.hpp +37 -0
  26. data/rice/Arg.hpp +8 -0
  27. data/rice/Arg_impl.hpp +116 -0
  28. data/rice/Arg_operators.cpp +21 -0
  29. data/rice/Arg_operators.hpp +18 -0
  30. data/rice/Array.hpp +220 -0
  31. data/rice/Array.ipp +263 -0
  32. data/rice/Builtin_Object.hpp +8 -0
  33. data/rice/Builtin_Object.ipp +50 -0
  34. data/rice/Builtin_Object_defn.hpp +51 -0
  35. data/rice/Class.cpp +57 -0
  36. data/rice/Class.hpp +8 -0
  37. data/rice/Class.ipp +6 -0
  38. data/rice/Class_defn.hpp +83 -0
  39. data/rice/Constructor.hpp +339 -0
  40. data/rice/Critical_Guard.hpp +40 -0
  41. data/rice/Critical_Guard.ipp +26 -0
  42. data/rice/Data_Object.hpp +8 -0
  43. data/rice/Data_Object.ipp +133 -0
  44. data/rice/Data_Object_defn.hpp +132 -0
  45. data/rice/Data_Type.cpp +21 -0
  46. data/rice/Data_Type.hpp +8 -0
  47. data/rice/Data_Type.ipp +306 -0
  48. data/rice/Data_Type_defn.hpp +219 -0
  49. data/rice/Data_Type_fwd.hpp +12 -0
  50. data/rice/Director.cpp +19 -0
  51. data/rice/Director.hpp +47 -0
  52. data/rice/Enum.hpp +118 -0
  53. data/rice/Enum.ipp +246 -0
  54. data/rice/Exception.cpp +59 -0
  55. data/rice/Exception.hpp +9 -0
  56. data/rice/Exception_Base.hpp +8 -0
  57. data/rice/Exception_Base.ipp +13 -0
  58. data/rice/Exception_Base_defn.hpp +27 -0
  59. data/rice/Exception_defn.hpp +69 -0
  60. data/rice/Hash.hpp +210 -0
  61. data/rice/Hash.ipp +338 -0
  62. data/rice/Identifier.cpp +8 -0
  63. data/rice/Identifier.hpp +50 -0
  64. data/rice/Identifier.ipp +33 -0
  65. data/rice/Jump_Tag.hpp +24 -0
  66. data/rice/Makefile.am +140 -0
  67. data/rice/Makefile.in +740 -0
  68. data/rice/Module.cpp +84 -0
  69. data/rice/Module.hpp +8 -0
  70. data/rice/Module.ipp +6 -0
  71. data/rice/Module_defn.hpp +88 -0
  72. data/rice/Module_impl.hpp +281 -0
  73. data/rice/Module_impl.ipp +348 -0
  74. data/rice/Object.cpp +153 -0
  75. data/rice/Object.hpp +8 -0
  76. data/rice/Object.ipp +19 -0
  77. data/rice/Object_defn.hpp +183 -0
  78. data/rice/Require_Guard.hpp +21 -0
  79. data/rice/String.cpp +94 -0
  80. data/rice/String.hpp +89 -0
  81. data/rice/Struct.cpp +117 -0
  82. data/rice/Struct.hpp +162 -0
  83. data/rice/Struct.ipp +26 -0
  84. data/rice/Symbol.cpp +25 -0
  85. data/rice/Symbol.hpp +66 -0
  86. data/rice/Symbol.ipp +44 -0
  87. data/rice/VM.cpp +92 -0
  88. data/rice/VM.hpp +32 -0
  89. data/rice/config.hpp +44 -0
  90. data/rice/config.hpp.in +43 -0
  91. data/rice/detail/Arguments.hpp +126 -0
  92. data/rice/detail/Auto_Function_Wrapper.hpp +861 -0
  93. data/rice/detail/Auto_Function_Wrapper.ipp +2929 -0
  94. data/rice/detail/Auto_Member_Function_Wrapper.hpp +828 -0
  95. data/rice/detail/Auto_Member_Function_Wrapper.ipp +2326 -0
  96. data/rice/detail/Caster.hpp +63 -0
  97. data/rice/detail/Exception_Handler.hpp +8 -0
  98. data/rice/detail/Exception_Handler.ipp +68 -0
  99. data/rice/detail/Exception_Handler_defn.hpp +96 -0
  100. data/rice/detail/Iterator.hpp +93 -0
  101. data/rice/detail/Not_Copyable.hpp +25 -0
  102. data/rice/detail/Wrapped_Function.hpp +33 -0
  103. data/rice/detail/check_ruby_type.cpp +27 -0
  104. data/rice/detail/check_ruby_type.hpp +23 -0
  105. data/rice/detail/creation_funcs.hpp +37 -0
  106. data/rice/detail/creation_funcs.ipp +36 -0
  107. data/rice/detail/default_allocation_func.hpp +23 -0
  108. data/rice/detail/default_allocation_func.ipp +11 -0
  109. data/rice/detail/define_method_and_auto_wrap.hpp +31 -0
  110. data/rice/detail/define_method_and_auto_wrap.ipp +30 -0
  111. data/rice/detail/demangle.cpp +56 -0
  112. data/rice/detail/demangle.hpp +19 -0
  113. data/rice/detail/env.hpp +19 -0
  114. data/rice/detail/from_ruby.hpp +43 -0
  115. data/rice/detail/from_ruby.ipp +60 -0
  116. data/rice/detail/method_data.cpp +392 -0
  117. data/rice/detail/method_data.cpp.rpp +301 -0
  118. data/rice/detail/method_data.hpp +21 -0
  119. data/rice/detail/mininode.cpp +1220 -0
  120. data/rice/detail/mininode.cpp.rpp +62 -0
  121. data/rice/detail/mininode.hpp +320 -0
  122. data/rice/detail/mininode.hpp.rpp +119 -0
  123. data/rice/detail/node.hpp +13 -0
  124. data/rice/detail/object_call.hpp +85 -0
  125. data/rice/detail/object_call.ipp +147 -0
  126. data/rice/detail/protect.cpp +29 -0
  127. data/rice/detail/protect.hpp +34 -0
  128. data/rice/detail/remove_const.hpp +21 -0
  129. data/rice/detail/ruby.hpp +89 -0
  130. data/rice/detail/ruby_version_code.hpp +6 -0
  131. data/rice/detail/ruby_version_code.hpp.in +6 -0
  132. data/rice/detail/rubysig.hpp +19 -0
  133. data/rice/detail/st.hpp +60 -0
  134. data/rice/detail/to_ruby.hpp +22 -0
  135. data/rice/detail/to_ruby.ipp +37 -0
  136. data/rice/detail/win32.hpp +16 -0
  137. data/rice/detail/wrap_function.hpp +345 -0
  138. data/rice/detail/wrap_function.ipp +531 -0
  139. data/rice/generate_code.rb +1311 -0
  140. data/rice/global_function.hpp +33 -0
  141. data/rice/global_function.ipp +22 -0
  142. data/rice/protect.hpp +91 -0
  143. data/rice/protect.ipp +803 -0
  144. data/rice/ruby_mark.hpp +13 -0
  145. data/rice/ruby_try_catch.hpp +86 -0
  146. data/rice/rubypp.rb +97 -0
  147. data/rice/to_from_ruby.hpp +8 -0
  148. data/rice/to_from_ruby.ipp +299 -0
  149. data/rice/to_from_ruby_defn.hpp +71 -0
  150. data/ruby.ac +150 -0
  151. data/ruby/Makefile.am +1 -0
  152. data/ruby/Makefile.in +497 -0
  153. data/ruby/lib/Makefile.am +3 -0
  154. data/ruby/lib/Makefile.in +374 -0
  155. data/ruby/lib/mkmf-rice.rb.in +209 -0
  156. data/ruby/lib/version.rb +3 -0
  157. data/sample/Makefile.am +47 -0
  158. data/sample/Makefile.in +380 -0
  159. data/sample/enum/extconf.rb +3 -0
  160. data/sample/enum/sample_enum.cpp +54 -0
  161. data/sample/enum/test.rb +8 -0
  162. data/sample/inheritance/animals.cpp +98 -0
  163. data/sample/inheritance/extconf.rb +3 -0
  164. data/sample/inheritance/test.rb +7 -0
  165. data/sample/map/extconf.rb +3 -0
  166. data/sample/map/map.cpp +81 -0
  167. data/sample/map/test.rb +7 -0
  168. data/test/Makefile.am +49 -0
  169. data/test/Makefile.in +603 -0
  170. data/test/test_Address_Registration_Guard.cpp +43 -0
  171. data/test/test_Allocation_Strategies.cpp +77 -0
  172. data/test/test_Array.cpp +241 -0
  173. data/test/test_Builtin_Object.cpp +72 -0
  174. data/test/test_Class.cpp +398 -0
  175. data/test/test_Constructor.cpp +238 -0
  176. data/test/test_Critical_Guard.cpp +51 -0
  177. data/test/test_Data_Object.cpp +275 -0
  178. data/test/test_Data_Type.cpp +121 -0
  179. data/test/test_Director.cpp +225 -0
  180. data/test/test_Enum.cpp +162 -0
  181. data/test/test_Exception.cpp +46 -0
  182. data/test/test_Hash.cpp +195 -0
  183. data/test/test_Identifier.cpp +70 -0
  184. data/test/test_Jump_Tag.cpp +17 -0
  185. data/test/test_Module.cpp +428 -0
  186. data/test/test_Object.cpp +148 -0
  187. data/test/test_String.cpp +94 -0
  188. data/test/test_Struct.cpp +192 -0
  189. data/test/test_Symbol.cpp +63 -0
  190. data/test/test_To_From_Ruby.cpp +263 -0
  191. data/test/test_VM.cpp +26 -0
  192. data/test/test_global_functions.cpp +97 -0
  193. data/test/test_rice.rb +35 -0
  194. data/test/unittest.cpp +136 -0
  195. data/test/unittest.hpp +292 -0
  196. metadata +247 -0
data/README ADDED
@@ -0,0 +1,879 @@
1
+ \mainpage Rice - Ruby Interface for C++ Extensions
2
+
3
+
4
+ \section intro Introduction
5
+
6
+ Rice is a C++ interface to Ruby's C API. It provides a type-safe and
7
+ exception-safe interface in order to make embedding Ruby and writing
8
+ Ruby extensions with C++ easier. It is similar to Boost.Python in many
9
+ ways, but also attempts to provide an object-oriented interface to all
10
+ of the Ruby C API.
11
+
12
+ What Rice gives you:
13
+ \li A simple C++-based syntax for wrapping and defining classes
14
+ \li Automatic conversion of exceptions between C++ and Ruby
15
+ \li Smart pointers for handling garbage collection
16
+ \li Wrappers for most builtin types to simplify calling code
17
+
18
+ \section installation Installation
19
+
20
+ There are two ways to install Rice. You can download the tarball from the project
21
+ page:
22
+
23
+ http://rubyforge.org/projects/rice
24
+
25
+ extract it and:
26
+
27
+ \code
28
+ ./configure
29
+ make
30
+ sudo make install
31
+ \endcode
32
+
33
+ or you can install via RubyGems
34
+
35
+ \code
36
+ gem install rice
37
+ \endcode
38
+
39
+ Note to Windows users: Rice is only known to properly compile and run under Cygwin and Mingw.
40
+
41
+ \section tutorial Tutorial
42
+
43
+ \subsection geting_started Getting started
44
+
45
+ Writing an extension with Rice is very similar to writing an extension
46
+ with the C API.
47
+
48
+ The first step is to create an extconf.rb file:
49
+
50
+ \code
51
+ require 'mkmf-rice'
52
+ create_makefile('test')
53
+ \endcode
54
+
55
+ Note that we use mkmf-rice instead of mkmf. This will ensure that the
56
+ extension will be linked with standard C++ library.
57
+
58
+ Next we create our extension and save it to test.cpp:
59
+
60
+ \code
61
+ extern "C"
62
+ void Init_Test()
63
+ {
64
+ }
65
+ \endcode
66
+
67
+ Note the extern "C" line above. This tells the compiler that the
68
+ function Init_Test should have C linkage and calling convention. This
69
+ turns off name mangling so that the Ruby interpreter will be able to
70
+ find the function (remember that Ruby is written in C, not C++).
71
+
72
+ So far we haven't put anything into the extension, so it isn't
73
+ particularly useful. The next step is to define a class so we can add
74
+ methods to it.
75
+
76
+
77
+ \subsection classes Defining clases
78
+
79
+ Defining a class in Rice is easy:
80
+
81
+ \code
82
+ #include "rice/Class.hpp"
83
+
84
+ using namespace Rice;
85
+
86
+ extern "C"
87
+ void Init_Test()
88
+ {
89
+ Class rb_cTest = define_class("Test");
90
+ }
91
+ \endcode
92
+
93
+ This will create a class called Test that inherits from Object. If we
94
+ wanted to inherit from a different class, we could easily do so:
95
+
96
+ \code
97
+ #include "rice/Class.hpp"
98
+
99
+ using namespace Rice;
100
+
101
+ extern "C"
102
+ void Init_Test()
103
+ {
104
+ Class rb_cMySocket = define_class("MySocket", rb_cIO);
105
+ }
106
+ \endcode
107
+
108
+ Note the prefix rb_c on the name of the class. This is a convention
109
+ that the Ruby interpreter and many extensions tend to use. It signifies
110
+ that this is a class and not some other type of object. Some other
111
+ naming conventions that are commonly used:
112
+
113
+ \li rb_c variable name prefix for a Class
114
+ \li rb_M variable name prefix for a Module
115
+ \li rb_e variable name prefix for an Exception type
116
+ \li rb_ function prefix for a function in the Ruby C API
117
+ \li rb_f_ function prefix to differentiate between an API function that
118
+ takes Ruby objects as arguments and one that takes C argument types
119
+ \li rb_*_s_ indicates the function is a singleton function
120
+ \li *_m suffix to indicate the function takes variable number of
121
+ arguments
122
+
123
+
124
+ Also note that we don't include "ruby.h" directly. Rice has a wrapper
125
+ for ruby.h that handles some compatibility issues across platforms and
126
+ Ruby versions. Always include Rice headers before including anything
127
+ that might include "ruby.h".
128
+
129
+ \subsection methods Defining methods
130
+
131
+ Now let's add a method to our class:
132
+
133
+ \code
134
+ #include "rice/Class.hpp"
135
+ #include "rice/String.hpp"
136
+
137
+ using namespace Rice;
138
+
139
+ Object test_hello(Object /* self */)
140
+ {
141
+ String str("hello, world");
142
+ return str;
143
+ }
144
+
145
+ extern "C"
146
+ void Init_Test()
147
+ {
148
+ Class rb_cTest =
149
+ define_class("Test")
150
+ .define_method("hello", test_hello);
151
+ }
152
+ \endcode
153
+
154
+ Here we add a method Test#hello that simply returns the string
155
+ "Hello, World". The method takes self as an implicit parameter, but
156
+ isn't used, so we comment it out to prevent a compiler warning.
157
+
158
+ We could also add an #initialize method to our class:
159
+
160
+ \code
161
+ #include "rice/Class.hpp"
162
+ #include "rice/String.hpp"
163
+
164
+ using namespace Rice;
165
+
166
+ Object test_initialize(Object self)
167
+ {
168
+ self.iv_set("@foo", 42);
169
+ }
170
+
171
+ Object test_hello(Object /* self */)
172
+ {
173
+ String str("hello, world");
174
+ return str;
175
+ }
176
+
177
+ extern "C"
178
+ void Init_Test()
179
+ {
180
+ Class rb_cTest =
181
+ define_class("Test")
182
+ .define_method("initialize", test_initialize);
183
+ .define_method("hello", test_hello);
184
+ }
185
+ \endcode
186
+
187
+ The initialize method sets an instance variable @foo to the value 42.
188
+ The number is automatically converted to a Fixnum before doing the
189
+ assignment.
190
+
191
+ Note that we're chaining calls on the Class object. Most member
192
+ functions in Module and Class return a reference to self, so we can
193
+ chain as many calls as we want to define as many methods as we want.
194
+
195
+
196
+ \subsection data_types Wrapping C++ Types
197
+
198
+ It's useful to be able to define Ruby classes in a C++ style rather than
199
+ using the Ruby API directly, but the real power Rice is in wrapping
200
+ already-defined C++ types.
201
+
202
+ Let's assume we have the following C++ class that we want to wrap:
203
+
204
+ \code
205
+ class Test
206
+ {
207
+ public:
208
+ Test();
209
+ std::string hello();
210
+ };
211
+ \endcode
212
+
213
+ This is a C++ version of the Ruby class we just created in the previous
214
+ section. To wrap it:
215
+
216
+ \code
217
+ #include "rice/Data_Type.hpp"
218
+ #include "rice/Constructor.hpp"
219
+
220
+ using namespace Rice;
221
+
222
+ extern "C"
223
+ void Init_Test()
224
+ {
225
+ Data_Type<Test> rb_cTest =
226
+ define_class<Test>("Test")
227
+ .define_constructor(Constructor<Test>())
228
+ .define_method("hello", &Test::hello);
229
+ }
230
+ \endcode
231
+
232
+ This example is similar to the one before, but we use Data_Type<>
233
+ instead of Class and the template version of define_class() instead of
234
+ the non-template version. This creates a binding in the Rice library
235
+ between the Ruby class Test and the C++ class Test, so that we pass
236
+ member function pointers to define_method() and have conversions be done
237
+ automatically.
238
+
239
+ It's possible to write the conversion functions ourself (as we'll see
240
+ below), but Rice does all the dirty work for us.
241
+
242
+
243
+ \subsection conversions Type conversions
244
+
245
+ Let's look again at our example class:
246
+
247
+ \code
248
+ class Test
249
+ {
250
+ public:
251
+ Test();
252
+ std::string hello();
253
+ };
254
+ \endcode
255
+
256
+ When we wrote our class, we never wrote a single line of code to convert
257
+ the std::string returned by hello() into a Ruby type. Neverthless, the
258
+ conversion works, and when we write:
259
+
260
+ \code
261
+ test = Test.new
262
+ puts test.hello
263
+ \endcode
264
+
265
+ We get the expected result.
266
+
267
+ Rice has two template conversion functions to convert between C++ and
268
+ Ruby types:
269
+
270
+ \code
271
+ template<typename T>
272
+ T from_ruby(Object x);
273
+
274
+ template<typename T>
275
+ Object to_ruby(T const & x);
276
+ \endcode
277
+
278
+ Rice has included by default specializations for many of the builtin
279
+ types. To define your own conversion, you can write a specialization:
280
+
281
+ \code
282
+ template<>
283
+ Foo from_ruby<Foo>(Object x)
284
+ {
285
+ // ...
286
+ }
287
+
288
+ template<>
289
+ Object to_ruby<Foo>(Foo const & x)
290
+ {
291
+ // ...
292
+ }
293
+ \endcode
294
+
295
+ The implementation of these functions would, of course, depend on the
296
+ implementation of Foo.
297
+
298
+
299
+ \subsection data_conversions Conversions for wrapped C++ types
300
+
301
+ Take another look at the wrapper we wrote for the Test class:
302
+
303
+ \code
304
+ extern "C"
305
+ void Init_Test()
306
+ {
307
+ Data_Type<Test> rb_cTest =
308
+ define_class<Test>("Test")
309
+ .define_constructor(Constructor<Test>())
310
+ .define_method("hello", &Test::hello);
311
+ }
312
+ \endcode
313
+
314
+ When we called define_class<Test>, it created a Class for us and
315
+ automatically registered the new Class with the type system, so that the
316
+ calls:
317
+
318
+ \code
319
+ Data_Object<Foo> obj(new Foo);
320
+ Foo * f = from_ruby<Foo *>(obj);
321
+ Foo const * f = from_ruby<Foo const *>(obj);
322
+ \endcode
323
+
324
+ work as expected.
325
+
326
+ The Data_Object class is a wrapper for the Data_Wrap_Struct and the
327
+ Data_Get_Struct macros in C extensions. It can be used to wrap or
328
+ unwrap any class that has been assigned to a Data_Type. It inherits
329
+ from Object, so any member functions we can call on an Object we can
330
+ also call on a Data_Object:
331
+
332
+ \code
333
+ Object object_id = obj.call("object_id");
334
+ std::cout << object_id << std::endl;
335
+ \endcode
336
+
337
+ The Data_Object class can be used to wrap a newly-created object:
338
+
339
+ \code
340
+ Data_Object<Foo> foo(new Foo);
341
+ \endcode
342
+
343
+ or to unwrap an already-created object:
344
+
345
+ \code
346
+ VALUE obj = ...;
347
+ Data_Object<Foo> foo(obj);
348
+ \endcode
349
+
350
+ A Data_Object functions like a smart pointer:
351
+
352
+ \code
353
+ Data_Object<Foo> foo(obj);
354
+ foo->foo();
355
+ std::cout << *foo << std::endl;
356
+ \endcode
357
+
358
+ Like a VALUE or an Object, data stored in a Data_Object will be marked
359
+ by the garbage collector as long as the Data_Object is on the stack.
360
+
361
+
362
+ \subsection exception Exceptions
363
+
364
+ Suppose we added a member function to our example class that throws an
365
+ exception:
366
+
367
+ \code
368
+ class MyException
369
+ : public std::exception
370
+ {
371
+ };
372
+
373
+ class Test
374
+ {
375
+ public:
376
+ Test();
377
+ std::string hello();
378
+ void error();
379
+ };
380
+ \endcode
381
+
382
+ If we were to wrap this function:
383
+
384
+ \code
385
+ extern "C"
386
+ void Init_Test()
387
+ {
388
+ Data_Type<Test> rb_cTest =
389
+ define_class<Test>("Test")
390
+ .define_constructor(Constructor<Test>())
391
+ .define_method("hello", &Test::hello)
392
+ .define_method("error", &Test::error);
393
+ }
394
+ \endcode
395
+
396
+ and call it from inside Ruby:
397
+
398
+ \code
399
+ test = Test.new
400
+ test.error()
401
+ \endcode
402
+
403
+ we would get an exception. Rice will automatically convert any
404
+ C++ exception it catches into a Ruby exception. But what if we wanted
405
+ to use a custom eror message when we convert the exception, or what if
406
+ we wanted to convert to a different type of exception? We can write
407
+ this:
408
+
409
+ \code
410
+ extern "C"
411
+ void Init_Test()
412
+ {
413
+ Data_Type<Test> rb_cTest =
414
+ define_class<Test>("Test")
415
+ .add_handler<MyException>(handle_my_exception)
416
+ .define_constructor(Constructor<Test>())
417
+ .define_method("hello", &Test::hello)
418
+ .define_method("error", &Test::error);
419
+ }
420
+ \endcode
421
+
422
+ The handle_my_exception function need only rethrow the exception as a
423
+ Rice::Exception:
424
+
425
+ \code
426
+ void handle_my_exception(MyException const & ex)
427
+ {
428
+ throw Exception(rb_eRuntimeError, "Goodnight, moon");
429
+ }
430
+ \endcode
431
+
432
+ And what if we want to call Ruby code from C++? These exceptions are
433
+ also converted:
434
+
435
+ \code
436
+ Object o;
437
+ o.call("some_function_that_raises", 42);
438
+
439
+ protect(rb_raise, rb_eRuntimeError, "some exception msg");
440
+ \endcode
441
+
442
+ Internally whenever Rice catches a C++ or a Ruby exception, it converts
443
+ it to an Exception object. This object will later be re-raised as a
444
+ Ruby exception when control is returned to the Ruby VM.
445
+
446
+ Rice uses a similar class called Jump_Tag to handle symbols thrown by
447
+ Ruby's throw/catch or other non-local jumps from inside the Ruby VM.
448
+
449
+
450
+ \subsection builtin Builtin types
451
+
452
+ You've seen this example:
453
+
454
+ \code
455
+ Object object_id = obj.call("object_id");
456
+ std::cout << object_id << std::endl;
457
+ \endcode
458
+
459
+ Rice mimics the Ruby class hierarchy as closely as it can given that C++
460
+ is statically typed. In fact, the above code also works for Classes:
461
+
462
+ \code
463
+ Class rb_cTest = define_class<Test>("Test");
464
+ Object object_id = rb_cTest.call("object_id");
465
+ std::cout << object_id << std::endl;
466
+ \endcode
467
+
468
+ Rice provides builtin wrappers for many builtin Ruby types, including:
469
+
470
+ \li Object
471
+ \li Module
472
+ \li Class
473
+ \li String
474
+ \li Array
475
+ \li Hash
476
+ \li Struct
477
+ \li Symbol
478
+ \li Exception
479
+
480
+ The Array and Hash types can even be iterated over the same way one
481
+ would iterate over an STL container:
482
+
483
+ \code
484
+ Array a;
485
+ a.push(to_ruby(42));
486
+ a.push(to_ruby(43));
487
+ a.push(to_ruby(44));
488
+ Array::iterator it = a.begin();
489
+ Array::iterator end = a.end();
490
+ for(; it != end; ++it)
491
+ {
492
+ std::cout << *it << std::endl;
493
+ }
494
+ \endcode
495
+
496
+ STL algorithms should also work as expected on Array and Hash containers.
497
+
498
+
499
+ \subsection inheritance Inheritance
500
+
501
+ Inheritance is a tricky problem to solve in extensions. This is because
502
+ wrapper functions for base classes typically don't know how to accept
503
+ pointers to derived classes. It is possible to write this logic, but
504
+ the code is nontrivial.
505
+
506
+ Forunately Rice handles this gracefully:
507
+
508
+ \code
509
+ class Base
510
+ {
511
+ public:
512
+ virtual void foo();
513
+ };
514
+
515
+ class Derived
516
+ : public Base
517
+ {
518
+ };
519
+
520
+ extern "C"
521
+ void Init_Test()
522
+ {
523
+ Data_Type<Base> rb_cBase =
524
+ define_class<Base>("Base")
525
+ .define_method("foo", &Base::foo);
526
+ Data_Type<Derived> rb_cDerived =
527
+ define_class<Derived, Base>("Derived");
528
+ }
529
+ \endcode
530
+
531
+ The second template parameter to define_class indicates that Derived
532
+ inherits from Base.
533
+
534
+ Rice does not yet support multiple inheritance, but it is believed that
535
+ this is possible through the use of mixins.
536
+
537
+
538
+ \subsection overloading Overloaded functions
539
+
540
+ If you try to create a member function pointer to an overloaded
541
+ function, you will get an error. So how do we wrap classes that have
542
+ overloaded functions?
543
+
544
+ Consider a class that uses this idiom for accessors:
545
+
546
+ \code
547
+ class Container
548
+ {
549
+ size_t capacity(); // Get the capacity
550
+ void capacity(size_t cap); // Set the capacity
551
+ };
552
+ \endcode
553
+
554
+ We can wrap this class by using typedefs:
555
+
556
+ \code
557
+ extern "C"
558
+ void Init_Container()
559
+ {
560
+ typedef size_t (*Container::get_capacity)();
561
+ typedef void (*Container::set_capacity)(size_t);
562
+
563
+ Data_Type<Container> rb_cContainer =
564
+ define_class<Container>("Container")
565
+ .define_method("capacity", get_capacity(&Container::capacity))
566
+ .define_method("capacity=", set_capacity(&Container::capacity))
567
+ }
568
+ \endcode
569
+
570
+ A future version of Rice may provide a simplified interface for this.
571
+
572
+
573
+ \subsection user_defined_conversions User-defined type conversions
574
+
575
+ Rice provides default conversions for many built-in types. Sometimes,
576
+ however, the default conversion is not their right conversion. For
577
+ example, consider a function:
578
+
579
+ \code
580
+ void foo(char * x);
581
+ \endcode
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
+ \comment : -- this comment is to satisfy vim syntax highlighting --
595
+
596
+ \code
597
+ extern "C"
598
+ void Init_Test()
599
+ {
600
+ define_global_function("foo", foo);
601
+ }
602
+ \endcode
603
+
604
+ It will likely have the wrong behavior.
605
+
606
+ To avoid this problem, it is necessary to write a wrapper function:
607
+
608
+ \code
609
+ Object wrap_foo(Object o)
610
+ {
611
+ char c = from_ruby<char>(o);
612
+ foo(&c);
613
+ return to_ruby(c);
614
+ }
615
+
616
+ extern "C"
617
+ void Init_Test()
618
+ {
619
+ define_global_function("foo", wrap_foo);
620
+ }
621
+ \endcode
622
+
623
+ Note that the out parameter is returned from wrap_foo, as Ruby does not
624
+ have pass-by-variable-reference (it uses pass-by-object-reference).
625
+
626
+ Future versions of Rice will have a cleaner way of dealing with this.
627
+
628
+ \section motivation Motivation
629
+
630
+ There are a number of common problems when writing C or C++ extensions
631
+ for Ruby:
632
+
633
+ \li Type safety. It is easy to mix-up integral types such as ID and
634
+ VALUE. Some of the functions in the Ruby API are not consistent with
635
+ which types they take (e.g. rb_const_defined takes an ID and
636
+ rb_mod_remove_const takes a Symbol).
637
+
638
+ \li DRY principle. Specifying the number of arguments that each wrapped
639
+ function takes is easy to get wrong. Adding a new argument to the
640
+ function means that the number of arguments passed to rb_define_method
641
+ must also be updated.
642
+
643
+ \li Type conversion. There are many different functions to convert data
644
+ to and from ruby types. Many of them have different semantics or
645
+ different forms. For example, to convert a string, one might use the
646
+ StringValue macro, but to convert a fixnum, one might use FIX2INT.
647
+ Unwrapping previously wrapped C data uses yet another form.
648
+
649
+ \li Exception safety. It is imperative that C++ exceptions never make
650
+ their way into C code, and it is also imperative that a Ruby exception
651
+ never escape while there are objects on the stack with nontrivial
652
+ destructors. Rules for when it is okay to use which exceptions are
653
+ difficult to get right, especially as code is maintained through time.
654
+
655
+ \li Thread safety. Because the Ruby interpreter is not threads-safe,
656
+ the Ruby interpreter must not be run from more than one thread.
657
+ Because of tricks the GC and scheduler play with the C stack, it's not
658
+ enough to ensure that only one thread runs the interpreter at any
659
+ given time; once the interpreter has been run from one thread, it must
660
+ only ever be run from that thread in the future. Additionally,
661
+ because Ruby copies the stack when it switches threads, C++ code must
662
+ be careful not to access objects in one Ruby thread that were created
663
+ on the stack in another Ruby thread.
664
+
665
+ \li C-based API. The Ruby API is not always convenient for accessing
666
+ Ruby data structurs such as Hash and Array, especially when writing C++
667
+ code, as the interface for these containers is not consistent with
668
+ standard containers.
669
+
670
+ \li Calling convention. Function pointers passed into the Ruby API must
671
+ follow the C calling convention. This means that it is not possible to
672
+ pass a pointer to a template function or static member function (that
673
+ is, it will work on some platforms, but isn't portable).
674
+
675
+ \li Inheritance. When wrapping C++ objects, it is easy to store a
676
+ pointer to a derived class, but then methods in the base class must have
677
+ knowledge of the derived class in order to unwrap the object. It is
678
+ possible to always store a pointer to the base class and then
679
+ dynamic_cast the pointer to the derived type when necessary, but this
680
+ can be slow and cumbersome, and it isn't likely to work with multiple
681
+ inheritance. A system that properly handles inheritance for all corner
682
+ cases is nontrivial.
683
+
684
+ \li Multiple inheritance. C++ supports true multiple inheritance, but
685
+ the Ruby object model uses single inheritance with mixins. When
686
+ wrapping a library whose public interface uses multiple inheritance,
687
+ care must be taken in constructing the mapping.
688
+
689
+ \li GC safety. All live Ruby objects must be marked during the garbage
690
+ collector's mark phase, otherwise they will be prematurely destroyed.
691
+ The general rule is that object references stored on the heap should be
692
+ either registered with rb_gc_register_address or marked by a data
693
+ object's mark function; object references stored on the stack will be
694
+ automatically marked, provided the Ruby interpreter was properly
695
+ initialized at startup.
696
+
697
+ \li Callbacks. C implements callbacks via function pointers, while ruby
698
+ typically implements callbacks via procs. Writing an adapter function
699
+ to call the proc is not difficult, but there is much opportunity for
700
+ error (particularly with exception-safety).
701
+
702
+ \li Data serialization. By default data objects defined at the C layer
703
+ are not marshalable. The user must explicitly define functions to
704
+ marshal the data member-by-member.
705
+
706
+ Rice addresses these issues in many ways:
707
+
708
+ \li Type safety. Rice provides encapsulation for all builtin types,
709
+ such as Object, Identifier, Class, Module, and String. It
710
+ automatically checks the dynamic type of an object before constructing
711
+ an instance of a wrapper.
712
+
713
+ \li DRY principle. Rice uses introspection through the use of templates
714
+ and function overloading to automatically determine the number and types
715
+ of arguments to functions. Default arguments must still be handled
716
+ explicitly, however.
717
+
718
+ \li Type conversions. Rice provides cast-style to_ruby<> and
719
+ from_ruby<> template functions to simplify explicit type conversions.
720
+ Automatic type conversions for parameters and return values are
721
+ generated for all wrapped functions.
722
+
723
+ \li Exception safety. Rice automatically converts common exceptions and
724
+ provides a mechanism for converting user-defined exception types. Rice
725
+ also provides convenience functions for converting exceptions when
726
+ calling back into ruby code.
727
+
728
+ \li Thread safety. Rice provides no mechanisms for dealing with thread
729
+ safety. Many common thread safety issues should be alleviated by YARV,
730
+ which supports POSIX threads.
731
+
732
+ \li C++-based API. Rice provides an object-oriented C++-style API to
733
+ most common functions in the Ruby C API.
734
+
735
+ \li Calling convention. Rice automatically uses C calling convention
736
+ for all function pointers passed into the Ruby API.
737
+
738
+ \li Inheritance. Rice provides automatic conversion to the base class
739
+ type when a wrapped member function is called on the base class.
740
+
741
+ \li Multiple inheritance. Rice provides no mechanism for multiple
742
+ inheritance. Multiple inheritance can be simulated via mixins, though
743
+ this is not yet as easy as it could be.
744
+
745
+ \li GC safety. Rice provides a handful of convenience classes for
746
+ interacting with the garbage collector. There are still basic rules
747
+ which must be followed to ensure that objects get properly destroyed.
748
+
749
+ \li Callbacks. Rice provides a handful of convenience classes for
750
+ dealing with callbacks.
751
+
752
+ \li Data serialization. Rice provides no mechanism for data
753
+ serialization, but it is likely this may be added in a future release.
754
+
755
+
756
+ \section what_not What Rice is Not
757
+
758
+ There are a number projects which server similar functions to Rice. Two
759
+ such popular projects are SWIG and Boost.Python. Rice has some
760
+ distinct features which set it apart from both of these projects.
761
+
762
+ Rice is not trying to replace SWIG. Rice is not a generic wrapper
763
+ interface generator. Rice is a C++ library for interfacing with the
764
+ Ruby C API. This provides a very natural way for C++ programmers to
765
+ wrap their C++ code, without having to learn a new domain-specific
766
+ language. However, there is no reason why SWIG and Rice could not work
767
+ together; a SWIG module could be written to generate Rice code. Such a
768
+ module would combine the portability of SWIG with the maintainability of
769
+ Rice (I have written extensions using both, and I have found Rice
770
+ extensions to be more maintainable when the interface is constantly
771
+ changing. Your mileage may vary).
772
+
773
+ Rice is also not trying to simply be a Ruby version of Boost.Python.
774
+ Rice does use some of the same template tricks that Boost.Python uses,
775
+ however there are some important distinctions. First of all,
776
+ Boost.Python attempts to create a declarative DSL in C++ using
777
+ templates. Rice is a wrapper around the Ruby C API and attempts to make
778
+ its interface look like an OO version of the API; this means that class
779
+ declarations look procedural rather than declarative. Secondly, the
780
+ Ruby object model is different from the python object model. This is
781
+ reflected in the interface to Rice; it mimics the Ruby object model at
782
+ the C++ level. Thirdly, Rice uses Ruby as a code generator; I find this
783
+ to be much more readable than using the Boost preprocessor library.
784
+
785
+
786
+ \section history History
787
+
788
+ Rice originated as a project to interface with C++-based trading
789
+ software at Automated Trading Desk in Mount Pleasant, South Carolina.
790
+ The Ruby bindings for Swig were at the time less mature than they are
791
+ today, and did not suit the needs of the project.
792
+
793
+ Excruby was written not as a wrapper for the Ruby API, but rather as a
794
+ set of helper functions and classes for interfacing with the Ruby
795
+ interpreter in an exception-safe manner. Over the course of five years,
796
+ the project grew into wrappers for pieces of the API, but the original
797
+ helper functions remained as part of the public interface.
798
+
799
+ This created confusion for the users of the library, because there were
800
+ multiple ways of accomplishing most tasks -- directly through the C API,
801
+ through a low-level wrapper around the C API, and through a high-level
802
+ abstraction of the lower-level interfaces.
803
+
804
+ Rice was then born in an attempt to clean up the interface. Rice keeps
805
+ the lower-level wrappers, but as an implementation detail; the public
806
+ interface is truly a high-level abstraction around the Ruby C API.
807
+
808
+
809
+ \section gc The GC
810
+
811
+ \li Objects are not automatically registered with the garbage collector.
812
+
813
+ \li If an Object is on the stack, it does not need to be registered with
814
+ the garbage collector.
815
+
816
+ \li If an Object is allocated on the heap or if it is a member of an
817
+ object that might be allocated on the heap, use an
818
+ Address_Registration_Guard to register the object with the garbage
819
+ collector.
820
+
821
+ \li If a reference counted object is being wrapped, or if another type
822
+ of smart pointer is wrapped, ensure that only one mechanism is used to
823
+ destroy the object. In general, the smart pointer manages the
824
+ allocation of the object, and Ruby should hold only a reference to the
825
+ smart pointer. When the garbage collector determines that it is time to
826
+ clean up the object, the smart pointer will be destroyed, decrementing
827
+ the reference count; when the reference count drops to 0, underlying
828
+ object will be destroyed.
829
+
830
+
831
+ \section embedding Embedding
832
+
833
+ You can embed the Ruby interpter in your application by using the VM
834
+ class:
835
+
836
+ \code
837
+ int main(int argc, char * argv[])
838
+ {
839
+ Rice::VM vm(argc, argv);
840
+ vm.run()
841
+ }
842
+ \endcode
843
+
844
+ If the VM is not initialized from main() -- from a callback, for example
845
+ -- then you may need to initialize the stack whenever you use Rice or
846
+ the Ruby API:
847
+
848
+ \code
849
+ std::auto_ptr<Rice::VM> vm;
850
+ Rice::Object obj;
851
+
852
+ void some_application_extension_init()
853
+ {
854
+ vm.reset(new Rice::VM("some_application"));
855
+ }
856
+
857
+ void some_application_extension_callback()
858
+ {
859
+ // Need to initialize the stack here, because we don't know if
860
+ // we are at the same stack depth as when the VM was initialized
861
+ vm->init_stack();
862
+
863
+ // Now do some work...
864
+ obj->call("some_callback_function")
865
+ }
866
+ \endcode
867
+
868
+ Be aware that initializing the Ruby VM can cause a call to exit() if
869
+ certain command-line options are specified. This has two implications:
870
+
871
+ \li an application that constructs a Ruby VM may terminate
872
+ unexpectedly if the options passed to the interpreter are not tightly
873
+ controlled (a security issue), and
874
+
875
+ \li an application that constructs a Ruby VM should not have any
876
+ objects with nontrivial destructors on the stack when the VM is
877
+ created, otherwise those objects might not get correctly destructed.
878
+
879
+ vim:ft=cpp:tw=72:ts=2:sw=2:fo=cqrtn:noci:si