rice 1.0.0

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