Significant rearrangment of some sections of the documentaiton. Also added additional information about exception handling and getter/setter methods.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@8677 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
acc52f93ff
commit
90bbdcd207
1 changed files with 221 additions and 172 deletions
|
|
@ -47,48 +47,50 @@
|
|||
<li><a href="#Ruby_nn28">Defining Aliases</a>
|
||||
<li><a href="#Ruby_nn29">Predicate Methods</a>
|
||||
<li><a href="#Ruby_nn30">Bang Methods</a>
|
||||
<li><a href="#Ruby_nn31">Getters and Setters</a>
|
||||
</ul>
|
||||
<li><a href="#Ruby_nn32">Input and output parameters</a>
|
||||
<li><a href="#Ruby_nn33">Simple exception handling </a>
|
||||
<li><a href="#Ruby_nn34">Typemaps</a>
|
||||
<li><a href="#Ruby_nn33">Exception handling </a>
|
||||
<ul>
|
||||
<li><a href="#Ruby_nn35">What is a typemap?</a>
|
||||
<li><a href="#Ruby_nn36">Ruby typemaps</a>
|
||||
<li><a href="#Ruby_nn37">Typemap variables</a>
|
||||
<li><a href="#Ruby_nn38">Useful Functions</a>
|
||||
<ul>
|
||||
<li><a href="#Ruby_nn39">C Datatypes to Ruby Objects</a>
|
||||
<li><a href="#Ruby_nn40">Ruby Objects to C Datatypes</a>
|
||||
<li><a href="#Ruby_nn41">Macros for VALUE</a>
|
||||
<li><a href="#Ruby_nn42">Exceptions</a>
|
||||
<li><a href="#Ruby_nn43">Iterators</a>
|
||||
<li><a href="#Ruby_nn34">Using the %exception directive </a>
|
||||
<li><a href="#Ruby_nn35">Raising exceptions </a>
|
||||
<li><a href="#Ruby_nn36">Exception classes </a>
|
||||
</ul>
|
||||
<li><a href="#Ruby_nn44">Typemap Examples</a>
|
||||
<li><a href="#Ruby_nn45">Converting a Ruby array to a char **</a>
|
||||
<li><a href="#Ruby_nn46">Collecting arguments in a hash</a>
|
||||
<li><a href="#Ruby_nn47">Pointer handling</a>
|
||||
<li><a href="#Ruby_nn37">Typemaps</a>
|
||||
<ul>
|
||||
<li><a href="#Ruby_nn48">Ruby Datatype Wrapping</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<li><a href="#Ruby_nn49">Operator overloading</a>
|
||||
<li><a href="#Ruby_nn38">What is a typemap?</a>
|
||||
<li><a href="#Ruby_nn39">Ruby typemaps</a>
|
||||
<li><a href="#Ruby_nn40">Typemap variables</a>
|
||||
<li><a href="#Ruby_nn41">Useful Functions</a>
|
||||
<ul>
|
||||
<li><a href="#Ruby_nn50">Example: STL Vector to Ruby Array</a>
|
||||
<li><a href="#Ruby_nn42">C Datatypes to Ruby Objects</a>
|
||||
<li><a href="#Ruby_nn43">Ruby Objects to C Datatypes</a>
|
||||
<li><a href="#Ruby_nn44">Macros for VALUE</a>
|
||||
<li><a href="#Ruby_nn45">Exceptions</a>
|
||||
<li><a href="#Ruby_nn46">Iterators</a>
|
||||
</ul>
|
||||
<li><a href="#Ruby_nn51">Advanced Topics</a>
|
||||
<li><a href="#Ruby_nn47">Typemap Examples</a>
|
||||
<li><a href="#Ruby_nn48">Converting a Ruby array to a char **</a>
|
||||
<li><a href="#Ruby_nn49">Collecting arguments in a hash</a>
|
||||
<li><a href="#Ruby_nn50">Pointer handling</a>
|
||||
<ul>
|
||||
<li><a href="#Ruby_nn52">Creating Multi-Module Packages</a>
|
||||
<li><a href="#Ruby_nn53">Defining Aliases</a>
|
||||
<li><a href="#Ruby_nn54">Predicate Methods</a>
|
||||
<li><a href="#Ruby_nn55">Specifying Mixin Modules</a>
|
||||
<li><a href="#Ruby_nn51">Ruby Datatype Wrapping</a>
|
||||
</ul>
|
||||
<li><a href="#Ruby_nn56">Memory Management</a>
|
||||
<li><a href="#Ruby_nn52">Example: STL Vector to Ruby Array</a>
|
||||
</ul>
|
||||
<li><a href="#Ruby_nn53">Advanced Topics</a>
|
||||
<ul>
|
||||
<li><a href="#Ruby_nn57">Mark and Sweep Garbage Collector </a>
|
||||
<li><a href="#Ruby_nn58">Object Ownership</a>
|
||||
<li><a href="#Ruby_nn59">Object Tracking</a>
|
||||
<li><a href="#Ruby_nn60">Mark Functions</a>
|
||||
<li><a href="#Ruby_nn61">Free Functions</a>
|
||||
<li><a href="#Ruby_nn54">Operator overloading</a>
|
||||
<li><a href="#Ruby_nn55">Creating Multi-Module Packages</a>
|
||||
<li><a href="#Ruby_nn56">Specifying Mixin Modules</a>
|
||||
</ul>
|
||||
<li><a href="#Ruby_nn57">Memory Management</a>
|
||||
<ul>
|
||||
<li><a href="#Ruby_nn58">Mark and Sweep Garbage Collector </a>
|
||||
<li><a href="#Ruby_nn59">Object Ownership</a>
|
||||
<li><a href="#Ruby_nn60">Object Tracking</a>
|
||||
<li><a href="#Ruby_nn61">Mark Functions</a>
|
||||
<li><a href="#Ruby_nn62">Free Functions</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -989,18 +991,18 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<div class="code">
|
||||
<pre>class MyArray {<br>public:<br> // Construct an empty array<br> MyArray();<br> <br> // Return the size of this array<br> size_t length() const;<br>};<br><br>%extend MyArray {<br> // MyArray#size is an alias for MyArray#length<br> size_t size() const {<br> return self->length();<br> }<br>}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<p> A better solution is to use the <tt>%alias</tt> directive (unique to
|
||||
SWIG's Ruby module). The previous example could then be rewritten as: </p>
|
||||
<div class="code">
|
||||
<pre>// MyArray#size is an alias for MyArray#length<br>%alias MyArray::length "size";<br><br>class MyArray {<br>public:<br> // Construct an empty array<br> MyArray();<br> <br> // Return the size of this array<br> size_t length() const;<br>};<br>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<p> Multiple aliases can be associated with a method by providing a comma-separated
|
||||
list of aliases to the <tt>%alias</tt> directive, e.g. </p>
|
||||
<div class="code">
|
||||
<pre>%alias MyArray::length "amount,quantity,size";</pre>
|
||||
</div>
|
||||
</div>
|
||||
<p> From an end-user's standpoint, there's no functional difference between these
|
||||
two approaches; i.e. they should get the same result from calling either <em>MyArray#size</em> or <em>MyArray#length</em>. However, when the <tt>%alias</tt> directive is
|
||||
used, SWIG doesn't need to generate all of the wrapper code that's usually
|
||||
|
|
@ -1020,19 +1022,19 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<div class="code">
|
||||
<pre>%rename("is_it_safe?") is_it_safe();<br><br>%typemap(out) int is_it_safe <br> "$result = ($1 != 0) ? Qtrue : Qfalse;";<br><br>int is_it_safe();<br>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<p> A better solution is to use the <tt>%predicate</tt> directive (unique
|
||||
to SWIG's Ruby module) to designate a method as a predicate method. For
|
||||
the previous example, this would look like: </p>
|
||||
<div class="code">
|
||||
<pre>%predicate is_it_safe();<br><br>int is_it_safe();<br>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<p>This method would be invoked from Ruby code like this:</p>
|
||||
<div class="code">
|
||||
<pre>irb(main):001:0> <b>Example::is_it_safe?</b><br>true<br>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<p> The <tt>%predicate</tt> directive is implemented using SWIG's
|
||||
"features" mechanism and so the same name matching rules used for other kinds
|
||||
of features apply (see the chapter on <a href="Customization.html#Customization">"Customization
|
||||
|
|
@ -1055,6 +1057,35 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
"features" mechanism and so the same name matching rules used for other kinds
|
||||
of features apply (see the chapter on <a href="Customization.html#Customization">"Customization
|
||||
Features"</a>) for more details). </p>
|
||||
<H3><a name="Ruby_nn31"></a>30.4.4 Getters and Setters</H3>
|
||||
|
||||
|
||||
<p> Often times a C++ library will expose properties through getter and setter methods. For example:</p>
|
||||
<div class="code">
|
||||
<pre>class Foo {
|
||||
Foo() {}
|
||||
|
||||
int getValue() { return value_; }
|
||||
|
||||
void setValue(int value) { value_ = value; }
|
||||
|
||||
private:
|
||||
int value_;
|
||||
};</pre>
|
||||
</div>
|
||||
<p>By default, SWIG will expose these methods to Ruby as <tt>get_value</tt> and <tt>set_value.</tt> However, it more natural for these methods to be exposed in Ruby as <tt>value</tt> and <tt>value=. </tt> That allows the methods to be used like this:</p>
|
||||
<div class="code">
|
||||
<pre>irb(main):001:0> <b>foo = Foo.new()</b>
|
||||
irb(main):002:0> <b>foo.value = 5</b>
|
||||
irb(main):003:0> <b>puts foo.value</b></pre>
|
||||
</div>
|
||||
<p> This can be done by using the %rename directive:</p>
|
||||
<div class="code">
|
||||
<pre>%rename("value") Foo::getValue();
|
||||
%rename("value=") Foo::setValue(int value);
|
||||
</pre>
|
||||
</div>
|
||||
<p> </p>
|
||||
<H2><a name="Ruby_nn32"></a>30.5 Input and output parameters</H2>
|
||||
|
||||
|
||||
|
|
@ -1134,17 +1165,22 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<div class="code">
|
||||
<pre>r, c = Example.get_dimensions(m)<br></pre>
|
||||
</div>
|
||||
<H2><a name="Ruby_nn33"></a>30.6 Simple exception handling </H2>
|
||||
<H2><a name="Ruby_nn33"></a>30.6 Exception handling </H2>
|
||||
|
||||
|
||||
<p>
|
||||
The SWIG <tt>%exception</tt> directive can be used to define a user-definable
|
||||
<H3><a name="Ruby_nn34"></a>30.6.1 Using the %exception directive </H3>
|
||||
|
||||
|
||||
<p>The SWIG <tt>%exception</tt> directive can be used to define a user-definable
|
||||
exception handler that can convert C/C++ errors into Ruby exceptions. The
|
||||
chapter on <a href="Customization.html#Customization">Customization Features</a>
|
||||
contains more details, but suppose you have a C++ class like the following :
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>class DoubleArray {<br> private:<br> int n;<br> double *ptr;<br> public:<br> // Create a new array of fixed size<br> DoubleArray(int size) {<br> ptr = new double[size];<br> n = size;<br> }<br> // Destroy an array<br> ~DoubleArray() {<br> delete ptr;<br> }<br> // Return the length of the array<br> int length() {<br> return n;<br> }<br><br> // Get an array item and perform bounds checking.<br> double getitem(int i) {<br> if ((i >= 0) && (i < n))<br> return ptr[i];<br> else<br> throw RangeError();<br> }<br> // Set an array item and perform bounds checking.<br> void setitem(int i, double val) {<br> if ((i >= 0) && (i < n))<br> ptr[i] = val;<br> else {<br> throw RangeError();<br> }<br> }<br> };<br></pre>
|
||||
<pre>class DoubleArray {<br> private:<br> int n;<br> double *ptr;<br> public:<br> // Create a new array of fixed size<br> DoubleArray(int size) {<br> ptr = new double[size];<br> n = size;<br> }
|
||||
<br> // Destroy an array<br> ~DoubleArray() {<br> delete ptr;<br> }
|
||||
<br> // Return the length of the array<br> int length() {<br> return n;<br> }<br><br> // Get an array item and perform bounds checking.<br> double getitem(int i) {<br> if ((i >= 0) && (i < n))<br> return ptr[i];<br> else<br> throw RangeError();<br> }
|
||||
<br> // Set an array item and perform bounds checking.<br> void setitem(int i, double val) {<br> if ((i >= 0) && (i < n))<br> ptr[i] = val;<br> else {<br> throw RangeError();<br> }<br> }<br> };<br></pre>
|
||||
</div>
|
||||
<p>
|
||||
Since several methods in this class can throw an exception for an out-of-bounds
|
||||
|
|
@ -1152,7 +1188,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
following in an interface file:
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>%exception {<br> try {<br> $action<br> }<br> catch (const RangeError&) {<br> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);<br> rb_raise(cpperror, "Range error.");<br> }<br>}<br><br>class DoubleArray {<br> ...<br>};<br></pre>
|
||||
<pre>%exception {<br> try {<br> $action<br> }<br> catch (const RangeError&) {<br> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);<br> rb_raise(cpperror, "Range error.");<br> }<br>}<br><br>class DoubleArray {<br> ...<br>};<br></pre>
|
||||
</div>
|
||||
<p>
|
||||
The exception handling code is inserted directly into generated wrapper
|
||||
|
|
@ -1165,7 +1201,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
handler to only apply to specific methods like this:
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>%exception getitem {<br> try {<br> $action<br> }<br> catch (const RangeError&) {<br> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);<br> rb_raise(cpperror, "Range error in getitem.");<br> }<br>}<br><br>%exception setitem {<br> try {<br> $action<br> }<br> catch (const RangeError&) {<br> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);<br> rb_raise(cpperror, "Range error in setitem.");<br> }<br>}<br></pre>
|
||||
<pre>%exception getitem {<br> try {<br> $action<br> }<br> catch (const RangeError&) {<br> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);<br> rb_raise(cpperror, "Range error in getitem.");<br> }<br>}<br><br>%exception setitem {<br> try {<br> $action<br> }<br> catch (const RangeError&) {<br> static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);<br> rb_raise(cpperror, "Range error in setitem.");<br> }<br>}<br></pre>
|
||||
</div>
|
||||
<p>
|
||||
In this case, the exception handler is only attached to methods and functions
|
||||
|
|
@ -1175,14 +1211,103 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
exception handling. See the chapter on <a href="Customization.html#Customization">Customization
|
||||
Features</a> for more examples.
|
||||
</p>
|
||||
<p>When raising a Ruby exception from C/C++, use the <tt>rb_raise()</tt> function
|
||||
as shown above. The first argument passed to <tt>rb_raise()</tt> is the
|
||||
exception type. You can raise a custom exception type (like the <tt>cpperror</tt>
|
||||
example shown above) or one of the built-in Ruby exception types. For a list of
|
||||
the standard Ruby exception classes, consult a Ruby reference such as <a href="http://www.rubycentral.com/book">
|
||||
<em>Programming Ruby</em></a>.
|
||||
</p>
|
||||
<H2><a name="Ruby_nn34"></a>30.7 Typemaps</H2>
|
||||
<H3><a name="Ruby_nn35"></a>30.6.2 Raising exceptions </H3>
|
||||
|
||||
|
||||
<p>There are three ways to raise exceptions from C++ code to Ruby. </p>
|
||||
<p>The first way is to use <tt>SWIG_exception(int code, const char *msg)</tt>. The following table shows the mappings from SWIG error codes to Ruby exceptions:</p>
|
||||
<table summary="Mapping between SWIG error codes and Ruby exceptions." width="80%" border="1">
|
||||
<tr>
|
||||
<td>SWIG_MemoryError</td>
|
||||
<td>rb_eNoMemError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_IOError</td>
|
||||
<td>rb_eIOError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_RuntimeError</td>
|
||||
<td>rb_eRuntimeError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_IndexError</td>
|
||||
<td>rb_eIndexError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_TypeError</td>
|
||||
<td>rb_eTypeError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_DivisionByZero</td>
|
||||
<td>rb_eZeroDivError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_OverflowError</td>
|
||||
<td>rb_eRangeError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_SyntaxError</td>
|
||||
<td>rb_eSyntaxError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_ValueError</td>
|
||||
<td>rb_eArgError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_SystemError</td>
|
||||
<td>rb_eFatal</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_AttributeError</td>
|
||||
<td>rb_eRuntimeError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_NullReferenceError</td>
|
||||
<td>rb_eNullReferenceError*</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_ObjectPreviouslyDeletedError</td>
|
||||
<td>rb_eObjectPreviouslyDeleted*</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SWIG_UnknownError</td>
|
||||
<td>rb_eRuntimeError</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">* These error classes are created by SWIG and are not built-in Ruby exception classes </td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>The second way to raise errors is to use <tt>SWIG_Raise(obj, type, desc)</tt>. Obj is a C++ instance of an exception class, type is a string specifying the type of exception (for example, "MyError") and desc is the SWIG description of the exception class. For example: </p>
|
||||
<p> %raise(SWIG_NewPointerObj(e, SWIGTYPE_p_AssertionFailedException, 0), ":AssertionFailedException", SWIGTYPE_p_AssertionFailedException);</p>
|
||||
<p>This is useful when you want to pass the current exception object directly to Ruby, particularly when the object is an instance of class marked as an <tt>%exceptionclass</tt> (see the next section for more information).</p>
|
||||
<p>Last, you can raise an exception by directly calling Ruby's C api. This is done by invoking the <tt>rb_raise()</tt> function. The first argument passed to <tt>rb_raise()</tt> is the
|
||||
exception type. You can raise a custom exception type or one of the built-in Ruby exception types.</p>
|
||||
<H3><a name="Ruby_nn36"></a>30.6.3 Exception classes </H3>
|
||||
|
||||
|
||||
<p>Starting with SWIG 1.3.28, the Ruby module supports the <tt>%exceptionclass</tt> directive, which is used to identify C++ classes that are used as exceptions. Classes that are marked with the <tt>%exceptionclass</tt> directive are exposed in Ruby as child classes of <tt>rb_eRuntimeError</tt>. This alows C++ exceptions to be directly mapped to Ruby exceptions, providing for a more natural integration between C++ code and Ruby code.</p>
|
||||
<div class="code">
|
||||
<pre> %exceptionclass CustomError;
|
||||
|
||||
%inline %{
|
||||
class CustomError { };
|
||||
|
||||
class Foo { <br> public:<br> void test() { throw CustomError; }
|
||||
};
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
<p>From Ruby you can now call this method like this:
|
||||
<div class="code">
|
||||
<pre>foo = Foo.new
|
||||
begin
|
||||
foo.test()
|
||||
rescue CustomError => e
|
||||
puts "Caught custom error"
|
||||
end </pre>
|
||||
</div>
|
||||
<p>For another example look at swig/Examples/ruby/exception_class.<br>
|
||||
<H2><a name="Ruby_nn37"></a>30.7 Typemaps</H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1195,7 +1320,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
of using SWIG---the default wrapping behavior is enough in most cases. Typemaps
|
||||
are only used if you want to change some aspect of the primitive C-Ruby
|
||||
interface.</p>
|
||||
<H3><a name="Ruby_nn35"></a>30.7.1 What is a typemap?</H3>
|
||||
<H3><a name="Ruby_nn38"></a>30.7.1 What is a typemap?</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1262,7 +1387,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<div class="code">
|
||||
<pre>puts Example.count('o','Hello World')<br>2<br></pre>
|
||||
</div>
|
||||
<H3><a name="Ruby_nn36"></a>30.7.2 Ruby typemaps</H3>
|
||||
<H3><a name="Ruby_nn39"></a>30.7.2 Ruby typemaps</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1319,7 +1444,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
Examples of these typemaps appears in the <a href="#ruby_typemap_examples">section
|
||||
on typemap examples</a>
|
||||
</p>
|
||||
<H3><a name="Ruby_nn37"></a>30.7.3 Typemap variables</H3>
|
||||
<H3><a name="Ruby_nn40"></a>30.7.3 Typemap variables</H3>
|
||||
|
||||
|
||||
Within a typemap, a number of special variables prefaced with a <tt>$</tt> may
|
||||
|
|
@ -1355,7 +1480,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<p><tt>$symname</tt></p>
|
||||
<div class="indent">The Ruby name of the wrapper function being created.
|
||||
</div>
|
||||
<H3><a name="Ruby_nn38"></a>30.7.4 Useful Functions</H3>
|
||||
<H3><a name="Ruby_nn41"></a>30.7.4 Useful Functions</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1365,19 +1490,19 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
by David Thomas and Andrew Hunt.)
|
||||
</p>
|
||||
<p> </p>
|
||||
<H4><a name="Ruby_nn39"></a>30.7.4.1 C Datatypes to Ruby Objects</H4>
|
||||
<H4><a name="Ruby_nn42"></a>30.7.4.1 C Datatypes to Ruby Objects</H4>
|
||||
|
||||
|
||||
<div class="code">
|
||||
<pre>INT2NUM(long or int) - int to Fixnum or Bignum<br>INT2FIX(long or int) - int to Fixnum (faster than INT2NUM)<br>CHR2FIX(char) - char to Fixnum<br>rb_str_new2(char*) - char* to String<br>rb_float_new(double) - double to Float<br></pre>
|
||||
</div>
|
||||
<H4><a name="Ruby_nn40"></a>30.7.4.2 Ruby Objects to C Datatypes</H4>
|
||||
<H4><a name="Ruby_nn43"></a>30.7.4.2 Ruby Objects to C Datatypes</H4>
|
||||
|
||||
|
||||
<div class="code">
|
||||
<pre> int NUM2INT(Numeric)<br> int FIX2INT(Numeric)<br> unsigned int NUM2UINT(Numeric)<br> unsigned int FIX2UINT(Numeric)<br> long NUM2LONG(Numeric)<br> long FIX2LONG(Numeric)<br>unsigned long FIX2ULONG(Numeric)<br> char NUM2CHR(Numeric or String)<br> char * STR2CSTR(String)<br> char * rb_str2cstr(String, int*length)<br> double NUM2DBL(Numeric)<br><br></pre>
|
||||
</div>
|
||||
<H4><a name="Ruby_nn41"></a>30.7.4.3 Macros for VALUE</H4>
|
||||
<H4><a name="Ruby_nn44"></a>30.7.4.3 Macros for VALUE</H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1392,7 +1517,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<div class="indent">capacity of the Ruby array</div>
|
||||
<p><tt>RARRAY(arr)->ptr</tt></p>
|
||||
<div class="indent">pointer to array storage</div>
|
||||
<H4><a name="Ruby_nn42"></a>30.7.4.4 Exceptions</H4>
|
||||
<H4><a name="Ruby_nn45"></a>30.7.4.4 Exceptions</H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1459,7 +1584,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
with the <tt>-w</tt> flag. The given format string <i>fmt</i> and remaining
|
||||
arguments are interpreted as with <tt>printf()</tt>.
|
||||
</div>
|
||||
<H4><a name="Ruby_nn43"></a>30.7.4.5 Iterators</H4>
|
||||
<H4><a name="Ruby_nn46"></a>30.7.4.5 Iterators</H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1498,14 +1623,14 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<div class="indent">
|
||||
Equivalent to Ruby's <tt>throw</tt>.
|
||||
</div>
|
||||
<H3><a name="Ruby_nn44"></a>30.7.5 Typemap Examples</H3>
|
||||
<H3><a name="Ruby_nn47"></a>30.7.5 Typemap Examples</H3>
|
||||
|
||||
|
||||
<p>
|
||||
This section includes a few examples of typemaps. For more examples, you might
|
||||
look at the examples in the <tt>Example/ruby</tt> directory.
|
||||
</p>
|
||||
<H3><a name="Ruby_nn45"></a>30.7.6 Converting a Ruby array to a char **</H3>
|
||||
<H3><a name="Ruby_nn48"></a>30.7.6 Converting a Ruby array to a char **</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1529,7 +1654,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
allocation is used to allocate memory for the array, the "freearg" typemap is
|
||||
used to later release this memory after the execution of the C function.
|
||||
</p>
|
||||
<H3><a name="Ruby_nn46"></a>30.7.7 Collecting arguments in a hash</H3>
|
||||
<H3><a name="Ruby_nn49"></a>30.7.7 Collecting arguments in a hash</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1642,7 +1767,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
the extension, can be found in the <tt>Examples/ruby/hashargs</tt> directory of
|
||||
the SWIG distribution.
|
||||
</p>
|
||||
<H3><a name="Ruby_nn47"></a>30.7.8 Pointer handling</H3>
|
||||
<H3><a name="Ruby_nn50"></a>30.7.8 Pointer handling</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1689,7 +1814,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<div class="indent">
|
||||
<pre>%typemap(in) Foo * {<br> SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);<br>}<br></pre>
|
||||
</div>
|
||||
<H4><a name="Ruby_nn48"></a>30.7.8.1 Ruby Datatype Wrapping</H4>
|
||||
<H4><a name="Ruby_nn51"></a>30.7.8.1 Ruby Datatype Wrapping</H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1710,34 +1835,17 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<div class="indent">Retrieves the original C pointer of type <i>c-type</i> from the
|
||||
data object <i>obj</i> and assigns that pointer to <i>ptr</i>.
|
||||
</div>
|
||||
<H2><a name="Ruby_nn49"></a>30.8 Operator overloading</H2>
|
||||
<H3><a name="Ruby_nn52"></a>30.7.9 Example: STL Vector to Ruby Array</H3>
|
||||
|
||||
|
||||
<p>
|
||||
SWIG allows operator overloading with, by using the <tt>%extend</tt> or <tt>%rename</tt>
|
||||
commands in SWIG and the following operator names (derived from Python):
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre><b> General</b> <br>__repr__ - inspect<br>__str__ - to_s<br>__cmp__ - <=><br>__hash__ - hash<br>__nonzero__ - nonzero?<br><br><b> Callable</b> <br>__call__ - call<br><br><b> Collection</b> <br>__len__ - length<br>__getitem__ - []<br>__setitem__ - []=<br><br><b> Numeric</b> <br>__add__ - +<br>__sub__ - -<br>__mul__ - *<br>__div__ - /<br>__mod__ - %<br>__divmod__ - divmod<br>__pow__ - **<br>__lshift__ - <<<br>__rshift__ - >><br>__and__ - &<br>__xor__ - ^<br>__or__ - |<br>__neg__ - -@<br>__pos__ - +@<br>__abs__ - abs<br>__invert__ - ~<br>__int__ - to_i<br>__float__ - to_f<br>__coerce__ - coerce<br><br><b>Additions in 1.3.13 </b> <br>__lt__ - < <br>__le__ - <=<br>__eq__ - ==<br>__gt__ - ><br>__ge__ - >=<br><br></pre>
|
||||
</div>
|
||||
<p>
|
||||
Note that although SWIG supports the <tt>__eq__</tt> magic method name for
|
||||
defining an equivalence operator, there is no separate method for handling <i>inequality</i>
|
||||
since Ruby parses the expression <i>a != b</i> as <i>!(a == b)</i>.
|
||||
</p>
|
||||
<H3><a name="Ruby_nn50"></a>30.8.1 Example: STL Vector to Ruby Array</H3>
|
||||
|
||||
|
||||
<p>
|
||||
<em><b>FIXME: This example is out of place here!</b></em>
|
||||
</p>
|
||||
<p>Another use for macros and type maps is to create a Ruby array from a STL vector
|
||||
<p><em><b>FIXME: This example is out of place here!</b></em></p>
|
||||
<p>Another use for macros and type maps is to create a Ruby array from a STL vector
|
||||
of pointers. In essence, copy of all the pointers in the vector into a Ruby
|
||||
array. The use of the macro is to make the typemap so generic that any vector
|
||||
with pointers can use the type map. The following is an example of how to
|
||||
construct this type of macro/typemap and should give insight into constructing
|
||||
similar typemaps for other STL structures:
|
||||
</p>
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>%define PTR_VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)<br>%typemap(out) vectorclassname &, const vectorclassname & {<br> VALUE arr = rb_ary_new2($1->size());<br> vectorclassname::iterator i = $1->begin(), iend = $1->end();<br> for ( ; i!=iend; i++ )<br> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));<br> $result = arr;<br>}<br>%typemap(out) vectorclassname, const vectorclassname {<br> VALUE arr = rb_ary_new2($1.size());<br> vectorclassname::iterator i = $1.begin(), iend = $1.end();<br> for ( ; i!=iend; i++ )<br> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));<br> $result = arr;<br>}<br>%enddef<br></pre>
|
||||
</div>
|
||||
|
|
@ -1762,18 +1870,34 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<div class="code">
|
||||
<pre>%define VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)<br>%typemap(out) vectorclassname &, const vectorclassname & {<br> VALUE arr = rb_ary_new2($1->size()); <br> vectorclassname::iterator i = $1->begin(), iend = $1->end();<br> for ( ; i!=iend; i++ )<br> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, &(*i)));<br> $result = arr;<br>}<br>%typemap(out) vectorclassname, const vectorclassname {<br> VALUE arr = rb_ary_new2($1.size()); <br> vectorclassname::iterator i = $1.begin(), iend = $1.end();<br> for ( ; i!=iend; i++ )<br> rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, &(*i)));<br> $result = arr;<br>}<br>%enddef<br></pre>
|
||||
</div>
|
||||
<H2><a name="Ruby_nn51"></a>30.9 Advanced Topics</H2>
|
||||
|
||||
<H2><a name="Ruby_nn53"></a>30.8 Advanced Topics</H2>
|
||||
|
||||
|
||||
<H3><a name="Ruby_nn52"></a>30.9.1 Creating Multi-Module Packages</H3>
|
||||
<H3><a name="Ruby_nn54"></a>30.8.1 Operator overloading</H3>
|
||||
|
||||
|
||||
<p>
|
||||
SWIG allows operator overloading with, by using the <tt>%extend</tt> or <tt>%rename</tt>
|
||||
commands in SWIG and the following operator names (derived from Python):
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre><b> General</b> <br>__repr__ - inspect<br>__str__ - to_s<br>__cmp__ - <=><br>__hash__ - hash<br>__nonzero__ - nonzero?<br><br><b> Callable</b> <br>__call__ - call<br><br><b> Collection</b> <br>__len__ - length<br>__getitem__ - []<br>__setitem__ - []=<br><br><b> Numeric</b> <br>__add__ - +<br>__sub__ - -<br>__mul__ - *<br>__div__ - /<br>__mod__ - %<br>__divmod__ - divmod<br>__pow__ - **<br>__lshift__ - <<<br>__rshift__ - >><br>__and__ - &<br>__xor__ - ^<br>__or__ - |<br>__neg__ - -@<br>__pos__ - +@<br>__abs__ - abs<br>__invert__ - ~<br>__int__ - to_i<br>__float__ - to_f<br>__coerce__ - coerce<br><br><b>Additions in 1.3.13 </b> <br>__lt__ - < <br>__le__ - <=<br>__eq__ - ==<br>__gt__ - ><br>__ge__ - >=<br><br></pre>
|
||||
</div>
|
||||
<p>
|
||||
Note that although SWIG supports the <tt>__eq__</tt> magic method name for
|
||||
defining an equivalence operator, there is no separate method for handling <i>inequality</i>
|
||||
since Ruby parses the expression <i>a != b</i> as <i>!(a == b)</i>.
|
||||
</p>
|
||||
<H3><a name="Ruby_nn55"></a>30.8.2 Creating Multi-Module Packages</H3>
|
||||
|
||||
|
||||
<p>
|
||||
The chapter on <a href="Modules.html">Working with Modules</a> discusses the
|
||||
basics of creating multi-module extensions with SWIG, and in particular the
|
||||
considerations for sharing runtime type information among the different
|
||||
modules.
|
||||
</p>
|
||||
</p>
|
||||
<p>As an example, consider one module's interface file (<tt>shape.i</tt>) that
|
||||
defines our base class:
|
||||
</p>
|
||||
|
|
@ -1836,83 +1960,8 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<div class="code">
|
||||
<pre>$ <b>irb</b><br>irb(main):001:0> <b>require 'shape'</b><br>true<br>irb(main):002:0> <b>require 'circle'</b><br>true<br>irb(main):003:0> <b>c = Circle::Circle.new(5, 5, 20)</b><br>#<Circle::Circle:0xa097208><br>irb(main):004:0> <b>c.kind_of? Shape::Shape</b><br>true<br>irb(main):005:0> <b>c.getX()</b><br>5.0<br></pre>
|
||||
</div>
|
||||
<H3><a name="Ruby_nn53"></a>30.9.2 Defining Aliases</H3>
|
||||
|
||||
|
||||
<p>
|
||||
It's a fairly common practice in the Ruby built-ins and standard library to
|
||||
provide aliases for method names. For example, <em>Array#size</em> is an alias
|
||||
for <em>Array#length</em>. If you'd like to provide an alias for one of your
|
||||
class' instance methods, one approach is to use SWIG's <tt>%extend</tt> directive
|
||||
to add a new method of the aliased name that calls the original function. For
|
||||
example:
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>class MyArray {<br>public:<br> // Construct an empty array<br> MyArray();<br> <br> // Return the size of this array<br> size_t length() const;<br>};<br><br>%extend MyArray {<br> // MyArray#size is an alias for MyArray#length<br> size_t size() const {<br> return self->length();<br> }<br>}<br></pre>
|
||||
</div>
|
||||
<p>
|
||||
A better solution is to instead use the <tt>%alias</tt> directive (unique to
|
||||
SWIG's Ruby module). The previous example could then be rewritten as:
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>// MyArray#size is an alias for MyArray#length<br>%alias MyArray::length "size";<br><br>class MyArray {<br>public:<br> // Construct an empty array<br> MyArray();<br> <br> // Return the size of this array<br> size_t length() const;<br>};<br></pre>
|
||||
</div>
|
||||
<p>
|
||||
Multiple aliases can be associated with a method by providing a comma-separated
|
||||
list of aliases to the <tt>%alias</tt> directive, e.g.
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>%alias MyArray::length "amount,quantity,size";</pre>
|
||||
</div>
|
||||
<p>
|
||||
From an end-user's standpoint, there's no functional difference between these
|
||||
two approaches; i.e. they should get the same result from calling either <em>MyArray#size</em>
|
||||
or <em>MyArray#length</em>. However, when the <tt>%alias</tt> directive is
|
||||
used, SWIG doesn't need to generate all of the wrapper code that's usually
|
||||
associated with added methods like our <em>MyArray::size()</em> example.
|
||||
</p>
|
||||
<p>Note that the <tt>%alias</tt> directive is implemented using SWIG's "features"
|
||||
mechanism and so the same name matching rules used for other kinds of features
|
||||
apply (see the chapter on <a href="Customization.html#Customization">"Customization
|
||||
Features"</a>) for more details).</p>
|
||||
<H3><a name="Ruby_nn54"></a>30.9.3 Predicate Methods</H3>
|
||||
|
||||
|
||||
<p>
|
||||
Predicate methods in Ruby are those which return either <tt>true</tt> or <tt>false</tt>.
|
||||
By convention, these methods' names end in a question mark; some examples from
|
||||
built-in Ruby classes include <em>Array#empty?</em> (which returns <tt>true</tt>
|
||||
for an array containing no elements) and <em>Object#instance_of?</em> (which
|
||||
returns <tt>true</tt> if the object is an instance of the specified class). For
|
||||
consistency with Ruby conventions you would also want your interface's
|
||||
predicate methods' names to end in a question mark and return <tt>true</tt> or <tt>false</tt>.
|
||||
</p>
|
||||
<p>One cumbersome solution to this problem is to rename the method (using SWIG's <tt>%rename</tt>
|
||||
directive) and provide a custom typemap that converts the function's actual
|
||||
return type to Ruby's <tt>true</tt> or <tt>false</tt>. For example:
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>%rename("is_it_safe?") is_it_safe();<br><br>%typemap(out) int is_it_safe <br> "$result = ($1 != 0) ? Qtrue : Qfalse;";<br><br>int is_it_safe();<br></pre>
|
||||
</div>
|
||||
<p>
|
||||
A better solution is to instead use the <tt>%predicate</tt> directive (unique
|
||||
to SWIG's Ruby module) to designate certain methods as predicate methods. For
|
||||
the previous example, this would look like:
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>%predicate is_it_safe();<br><br>int is_it_safe();<br></pre>
|
||||
</div>
|
||||
<p>and to use this method from your Ruby code:</p>
|
||||
<div class="code">
|
||||
<pre>irb(main):001:0> <b>Example::is_it_safe?</b><br>true<br></pre>
|
||||
</div>
|
||||
<p>
|
||||
Note that the <tt>%predicate</tt> directive is implemented using SWIG's
|
||||
"features" mechanism and so the same name matching rules used for other kinds
|
||||
of features apply (see the chapter on <a href="Customization.html#Customization">"Customization
|
||||
Features"</a>) for more details).
|
||||
</p>
|
||||
<H3><a name="Ruby_nn55"></a>30.9.4 Specifying Mixin Modules</H3>
|
||||
<H3><a name="Ruby_nn56"></a>30.8.3 Specifying Mixin Modules</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1953,7 +2002,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
apply (see the chapter on <a href="Customization.html#Customization">"Customization
|
||||
Features"</a>) for more details).
|
||||
</p>
|
||||
<H2><a name="Ruby_nn56"></a>30.10 Memory Management</H2>
|
||||
<H2><a name="Ruby_nn57"></a>30.9 Memory Management</H2>
|
||||
|
||||
|
||||
<p>One of the most common issues in generating SWIG bindings for Ruby is proper
|
||||
|
|
@ -1972,7 +2021,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
versa) depending on what function or methods are invoked. Clearly, developing a
|
||||
SWIG wrapper requires a thorough understanding of how the underlying library
|
||||
manages memory.</p>
|
||||
<H3><a name="Ruby_nn57"></a>30.10.1 Mark and Sweep Garbage Collector </H3>
|
||||
<H3><a name="Ruby_nn58"></a>30.9.1 Mark and Sweep Garbage Collector </H3>
|
||||
|
||||
|
||||
<p>Ruby uses a mark and sweep garbage collector. When the garbage collector runs,
|
||||
|
|
@ -1998,7 +2047,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
allocated in creating the underlying C struct or C++ struct, then a "free"
|
||||
function must be defined that deallocates this memory.
|
||||
</p>
|
||||
<H3><a name="Ruby_nn58"></a>30.10.2 Object Ownership</H3>
|
||||
<H3><a name="Ruby_nn59"></a>30.9.2 Object Ownership</H3>
|
||||
|
||||
|
||||
<p>As described above, memory management depends on clearly defining who is
|
||||
|
|
@ -2073,7 +2122,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
<p>
|
||||
This code can be seen in swig/examples/ruby/tracking.</p>
|
||||
<br>
|
||||
<H3><a name="Ruby_nn59"></a>30.10.3 Object Tracking</H3>
|
||||
<H3><a name="Ruby_nn60"></a>30.9.3 Object Tracking</H3>
|
||||
|
||||
|
||||
<p>The remaining parts of this section will use the class library shown below to
|
||||
|
|
@ -2142,7 +2191,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
implement your own free functions (see below) you may also have to call the<tt>SWIG_RubyRemoveTracking</tt>
|
||||
and <tt>RubyUnlinkObjects</tt> methods.</p>
|
||||
|
||||
<H3><a name="Ruby_nn60"></a>30.10.4 Mark Functions</H3>
|
||||
<H3><a name="Ruby_nn61"></a>30.9.4 Mark Functions</H3>
|
||||
|
||||
|
||||
<p>With a bit more testing, we see that our class library still has problems. For
|
||||
|
|
@ -2184,7 +2233,7 @@ $ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/
|
|||
</div>
|
||||
<br>
|
||||
<p>This code can be seen in swig/examples/ruby/mark_function.</p>
|
||||
<H3><a name="Ruby_nn61"></a>30.10.5 Free Functions</H3>
|
||||
<H3><a name="Ruby_nn62"></a>30.9.5 Free Functions</H3>
|
||||
|
||||
|
||||
<p>By default, SWIG creates a "free" function that is called when a Ruby object is
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue