Thousands of changes to correct incorrect HTML. HTML is now valid (transitional 4.01).
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6074 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
7cb896a5f4
commit
aa4d1d907d
31 changed files with 6754 additions and 4801 deletions
|
|
@ -4,77 +4,76 @@
|
|||
<title>SWIG and Ruby</title>
|
||||
</head>
|
||||
<body bgcolor="#ffffff">
|
||||
<a name="n1"></a>
|
||||
<a name="n1"></a><H1>23 SWIG and Ruby</H1>
|
||||
<H1><a name="Ruby"></a>26 SWIG and Ruby</H1>
|
||||
<!-- INDEX -->
|
||||
<ul>
|
||||
<li><a href="#n2">Preliminaries</a>
|
||||
<li><a href="#Ruby_nn2">Preliminaries</a>
|
||||
<ul>
|
||||
<li><a href="#n3">Running SWIG</a>
|
||||
<li><a href="#n4">Getting the right header files</a>
|
||||
<li><a href="#n5">Compiling a dynamic module</a>
|
||||
<li><a href="#n6">Using your module</a>
|
||||
<li><a href="#n7">Static linking</a>
|
||||
<li><a href="#n8">Compilation of C++ extensions</a>
|
||||
<li><a href="#Ruby_nn3">Running SWIG</a>
|
||||
<li><a href="#Ruby_nn4">Getting the right header files</a>
|
||||
<li><a href="#Ruby_nn5">Compiling a dynamic module</a>
|
||||
<li><a href="#Ruby_nn6">Using your module</a>
|
||||
<li><a href="#Ruby_nn7">Static linking</a>
|
||||
<li><a href="#Ruby_nn8">Compilation of C++ extensions</a>
|
||||
</ul>
|
||||
<li><a href="#n9">Building Ruby Extensions under Windows 95/NT</a>
|
||||
<li><a href="#Ruby_nn9">Building Ruby Extensions under Windows 95/NT</a>
|
||||
<ul>
|
||||
<li><a href="#n10">Running SWIG from Developer Studio</a>
|
||||
<li><a href="#Ruby_nn10">Running SWIG from Developer Studio</a>
|
||||
</ul>
|
||||
<li><a href="#n11">The Ruby-to-C/C++ Mapping</a>
|
||||
<li><a href="#Ruby_nn11">The Ruby-to-C/C++ Mapping</a>
|
||||
<ul>
|
||||
<li><a href="#n12">Modules</a>
|
||||
<li><a href="#n13">Functions</a>
|
||||
<li><a href="#n14">Variable Linking</a>
|
||||
<li><a href="#n15">Constants</a>
|
||||
<li><a href="#n16">Pointers</a>
|
||||
<li><a href="#n17">Structures</a>
|
||||
<li><a href="#n18">C++ classes</a>
|
||||
<li><a href="#n19">C++ Inheritance</a>
|
||||
<li><a href="#n20">C++ Overloaded Functions</a>
|
||||
<li><a href="#n21">C++ Operators</a>
|
||||
<li><a href="#n22">C++ namespaces</a>
|
||||
<li><a href="#n23">C++ templates</a>
|
||||
<li><a href="#n24">C++ Smart Pointers</a>
|
||||
<li><a href="#n25">Cross-Language Polymorphism</a>
|
||||
<li><a href="#Ruby_nn12">Modules</a>
|
||||
<li><a href="#Ruby_nn13">Functions</a>
|
||||
<li><a href="#Ruby_nn14">Variable Linking</a>
|
||||
<li><a href="#Ruby_nn15">Constants</a>
|
||||
<li><a href="#Ruby_nn16">Pointers</a>
|
||||
<li><a href="#Ruby_nn17">Structures</a>
|
||||
<li><a href="#Ruby_nn18">C++ classes</a>
|
||||
<li><a href="#Ruby_nn19">C++ Inheritance</a>
|
||||
<li><a href="#Ruby_nn20">C++ Overloaded Functions</a>
|
||||
<li><a href="#Ruby_nn21">C++ Operators</a>
|
||||
<li><a href="#Ruby_nn22">C++ namespaces</a>
|
||||
<li><a href="#Ruby_nn23">C++ templates</a>
|
||||
<li><a href="#ruby_cpp_smart_pointers">C++ Smart Pointers</a>
|
||||
<li><a href="#Ruby_nn25">Cross-Language Polymorphism</a>
|
||||
<ul>
|
||||
<li><a href="#n26">Exception Unrolling</a>
|
||||
<li><a href="#Ruby_nn26">Exception Unrolling</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<li><a href="#n27">Input and output parameters</a>
|
||||
<li><a href="#n28">Simple exception handling </a>
|
||||
<li><a href="#n29">Typemaps</a>
|
||||
<li><a href="#Ruby_nn27">Input and output parameters</a>
|
||||
<li><a href="#Ruby_nn28">Simple exception handling </a>
|
||||
<li><a href="#Ruby_nn29">Typemaps</a>
|
||||
<ul>
|
||||
<li><a href="#n30">What is a typemap?</a>
|
||||
<li><a href="#n31">Ruby typemaps</a>
|
||||
<li><a href="#n32">Typemap variables</a>
|
||||
<li><a href="#n33">Useful Functions</a>
|
||||
<li><a href="#Ruby_nn30">What is a typemap?</a>
|
||||
<li><a href="#Ruby_nn31">Ruby typemaps</a>
|
||||
<li><a href="#Ruby_nn32">Typemap variables</a>
|
||||
<li><a href="#Ruby_nn33">Useful Functions</a>
|
||||
<ul>
|
||||
<li><a href="#n34">C Datatypes to Ruby Objects</a>
|
||||
<li><a href="#n35">Ruby Objects to C Datatypes</a>
|
||||
<li><a href="#n36">Macros for VALUE</a>
|
||||
<li><a href="#n37">Exceptions</a>
|
||||
<li><a href="#n38">Iterators</a>
|
||||
<li><a href="#Ruby_nn34">C Datatypes to Ruby Objects</a>
|
||||
<li><a href="#Ruby_nn35">Ruby Objects to C Datatypes</a>
|
||||
<li><a href="#Ruby_nn36">Macros for VALUE</a>
|
||||
<li><a href="#Ruby_nn37">Exceptions</a>
|
||||
<li><a href="#Ruby_nn38">Iterators</a>
|
||||
</ul>
|
||||
<li><a href="#n39">Typemap Examples</a>
|
||||
<li><a href="#n40">Converting a Ruby array to a char **</a>
|
||||
<li><a href="#n41">Collecting arguments in a hash</a>
|
||||
<li><a href="#n42">Pointer handling</a>
|
||||
<li><a href="#ruby_typemap_examples">Typemap Examples</a>
|
||||
<li><a href="#Ruby_nn40">Converting a Ruby array to a char **</a>
|
||||
<li><a href="#Ruby_nn41">Collecting arguments in a hash</a>
|
||||
<li><a href="#Ruby_nn42">Pointer handling</a>
|
||||
<ul>
|
||||
<li><a href="#n43">Ruby Datatype Wrapping</a>
|
||||
<li><a href="#Ruby_nn43">Ruby Datatype Wrapping</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<li><a href="#n44">Operator overloading</a>
|
||||
<li><a href="#ruby_operator_overloading">Operator overloading</a>
|
||||
<ul>
|
||||
<li><a href="#n45">Example: STL Vector to Ruby Array</a>
|
||||
<li><a href="#Ruby_nn45">Example: STL Vector to Ruby Array</a>
|
||||
</ul>
|
||||
<li><a href="#n46">Advanced Topics</a>
|
||||
<li><a href="#Ruby_nn46">Advanced Topics</a>
|
||||
<ul>
|
||||
<li><a href="#n47">Creating Multi-Module Packages</a>
|
||||
<li><a href="#n48">Defining Aliases</a>
|
||||
<li><a href="#n49">Predicate Methods</a>
|
||||
<li><a href="#n50">Specifying Mixin Modules</a>
|
||||
<li><a href="#n51">Interacting with Ruby's Garbage Collector</a>
|
||||
<li><a href="#Ruby_nn47">Creating Multi-Module Packages</a>
|
||||
<li><a href="#Ruby_nn48">Defining Aliases</a>
|
||||
<li><a href="#Ruby_nn49">Predicate Methods</a>
|
||||
<li><a href="#Ruby_nn50">Specifying Mixin Modules</a>
|
||||
<li><a href="#Ruby_nn51">Interacting with Ruby's Garbage Collector</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<!-- INDEX -->
|
||||
|
|
@ -83,7 +82,7 @@
|
|||
|
||||
<p>This chapter describes SWIG's support of Ruby. </p>
|
||||
<hr><a name="n2"></a>
|
||||
<a name="n2"></a><H2>23.1 Preliminaries</H2>
|
||||
<H2><a name="Ruby_nn2"></a>26.1 Preliminaries</H2>
|
||||
|
||||
|
||||
SWIG 1.3 is known to work with Ruby versions 1.6 and later. Given the
|
||||
|
|
@ -96,23 +95,22 @@ without dynamic loading, but the compilation process will vary.
|
|||
<p>This chapter covers most SWIG features, but in less depth than is
|
||||
found in
|
||||
earlier chapters. At the very least, make sure you also read the "<a
|
||||
href="SWIG.html">SWIG Basics</a>" chapter. It is also assumed that the
|
||||
href="SWIG.html#SWIG">SWIG Basics</a>" chapter. It is also assumed that the
|
||||
reader
|
||||
has a basic understanding of Ruby.
|
||||
<a name="n3"></a></p>
|
||||
<a name="n3"></a><H3>23.1.1 Running SWIG</H3>
|
||||
|
||||
<H3><a name="Ruby_nn3"></a>26.1.1 Running SWIG</H3>
|
||||
|
||||
|
||||
<p>
|
||||
To build a Ruby module, run SWIG using the <tt>-ruby</tt> option:</p>
|
||||
<p></p>
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>swig -ruby example.i</b>
|
||||
</pre>
|
||||
</blockquote>
|
||||
If building a C++ extension, add the <tt>-c++</tt> option:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>swig -c++ -ruby example.i</b>
|
||||
</pre>
|
||||
|
|
@ -125,13 +123,16 @@ build a
|
|||
Ruby extension module. To finish building the module, you need to
|
||||
compile this
|
||||
file and link it with the rest of your program.
|
||||
<a name="n4"></a></p>
|
||||
<a name="n4"></a><H3>23.1.2 Getting the right header files</H3>
|
||||
|
||||
|
||||
<H3><a name="Ruby_nn4"></a>26.1.2 Getting the right header files</H3>
|
||||
|
||||
|
||||
<p>
|
||||
In order to compile the wrapper code, the compiler needs the <tt>ruby.h</tt>
|
||||
header file. This file is usually contained in a directory such as
|
||||
<p></p>
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>/usr/local/lib/ruby/1.6/i686-linux/ruby.h<br></pre>
|
||||
</blockquote>
|
||||
|
|
@ -149,8 +150,7 @@ can run Ruby to find out. For example:
|
|||
|
||||
</pre>
|
||||
</blockquote>
|
||||
<a name="n5"></a>
|
||||
<a name="n5"></a><H3>23.1.3 Compiling a dynamic module</H3>
|
||||
<H3><a name="Ruby_nn5"></a>26.1.3 Compiling a dynamic module</H3>
|
||||
|
||||
|
||||
Ruby extension modules are typically compiled into shared libraries
|
||||
|
|
@ -160,7 +160,7 @@ doing
|
|||
this vary from platform to platform, your best bet is to follow the
|
||||
steps
|
||||
described in the <tt>README.EXT</tt> file from the Ruby distribution:
|
||||
<p></p>
|
||||
|
||||
<ol>
|
||||
<li>Create a file called <tt>extconf.rb</tt> that looks like the
|
||||
following:
|
||||
|
|
@ -169,7 +169,6 @@ following:
|
|||
</blockquote>
|
||||
</li>
|
||||
<li>Type the following to build the extension:
|
||||
<p></p>
|
||||
<blockquote>
|
||||
<pre>$ <b>ruby extconf.rb</b>
|
||||
$ <b>make</b>
|
||||
|
|
@ -194,7 +193,7 @@ platform.
|
|||
For example, a typical sequence of commands for the Linux operating
|
||||
system
|
||||
would look something like this:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>swig -ruby example.i</b>
|
||||
$ <b>gcc -c example.c</b>
|
||||
|
|
@ -210,23 +209,22 @@ You might also check the <a
|
|||
href="http://swig.cs.uchicago.edu/cgi-bin/wiki.pl">
|
||||
SWIG Wiki</a> for additional information.
|
||||
<p> <a name="n6"></a></p>
|
||||
<a name="n6"></a><H3>23.1.4 Using your module</H3>
|
||||
<H3><a name="Ruby_nn6"></a>26.1.4 Using your module</H3>
|
||||
|
||||
|
||||
Ruby <i>module</i> names must be capitalized, but the convention for
|
||||
Ruby
|
||||
<i>feature</i> names is to use lowercase names. So, for example, the <b>Etc</b>
|
||||
extension module is imported by requiring the <b>etc</b> feature:
|
||||
<pre><blockquote># The feature name begins with a lowercase letter...<br>require 'etc'<br><br># ... but the module name begins with an uppercase letter<br>puts "Your login name: #{Etc.getlogin}"<br></blockquote></pre>
|
||||
<blockquote><pre># The feature name begins with a lowercase letter...<br>require 'etc'<br><br># ... but the module name begins with an uppercase letter<br>puts "Your login name: #{Etc.getlogin}"<br></pre></blockquote>
|
||||
To stay consistent with this practice, you should always specify a
|
||||
<b>lowercase</b> module name with SWIG's <tt>%module</tt> directive.
|
||||
SWIG will automatically correct the resulting Ruby module name for your
|
||||
extension. So for example, a SWIG interface file that begins with:
|
||||
<pre><blockquote>%module example<br></blockquote></pre>
|
||||
<blockquote><pre>%module example<br></pre></blockquote>
|
||||
will result in an extension module using the feature name "example" and
|
||||
Ruby module name "Example".
|
||||
<a name="n7"></a>
|
||||
<a name="n7"></a><H3>23.1.5 Static linking</H3>
|
||||
<H3><a name="Ruby_nn7"></a>26.1.5 Static linking</H3>
|
||||
|
||||
|
||||
An alternative approach to dynamic linking is to rebuild the Ruby
|
||||
|
|
@ -243,14 +241,14 @@ adding your directory to the list of extensions in the file, and
|
|||
finally rebuilding Ruby.
|
||||
</p>
|
||||
<p><a name="n8"></a></p>
|
||||
<a name="n8"></a><H3>23.1.6 Compilation of C++ extensions</H3>
|
||||
<H3><a name="Ruby_nn8"></a>26.1.6 Compilation of C++ extensions</H3>
|
||||
|
||||
|
||||
<p>
|
||||
On most machines, C++ extension modules should be linked using the C++
|
||||
compiler. For example:
|
||||
</p>
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>swig -c++ -ruby example.i</b>
|
||||
$ <b>g++ -c example.cxx</b>
|
||||
|
|
@ -276,8 +274,7 @@ into your extension, e.g.
|
|||
<pre>require 'mkmf'<br>$libs = append_library($libs, "supc++")<br>create_makefile('example')<br></pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<a name="n9"></a>
|
||||
<a name="n9"></a><H2>23.2 Building Ruby Extensions under Windows 95/NT</H2>
|
||||
<H2><a name="Ruby_nn9"></a>26.2 Building Ruby Extensions under Windows 95/NT</H2>
|
||||
|
||||
|
||||
Building a SWIG extension to Ruby under Windows 95/NT is roughly
|
||||
|
|
@ -306,7 +303,7 @@ you may need to download the source distribution to the Ruby package,
|
|||
as you
|
||||
will need the Ruby header files.
|
||||
<p><a name="n10"></a></p>
|
||||
<a name="n10"></a><H3>23.2.1 Running SWIG from Developer Studio</H3>
|
||||
<H3><a name="Ruby_nn10"></a>26.2.1 Running SWIG from Developer Studio</H3>
|
||||
|
||||
|
||||
If you are developing your application within Microsoft developer
|
||||
|
|
@ -314,8 +311,7 @@ studio, SWIG
|
|||
can be invoked as a custom build option. The process roughly follows
|
||||
these
|
||||
steps :
|
||||
<p></p>
|
||||
<p></p>
|
||||
|
||||
<ul>
|
||||
<li>Open up a new workspace and use the AppWizard to select a DLL
|
||||
project.
|
||||
|
|
@ -381,8 +377,7 @@ run
|
|||
your new Ruby extension, simply run Ruby and use the <tt>require</tt>
|
||||
command
|
||||
as normal. For example if you have this ruby file run.rb:</p>
|
||||
<p></p>
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre># file: run.rb<br>require 'Example'<br><br># Call a c function<br>print "Foo = ", Example.Foo, "\n"<br></pre>
|
||||
</blockquote>
|
||||
|
|
@ -394,17 +389,15 @@ Ruby script from the DOS/Command prompt:
|
|||
Foo = 3.0
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
</p>
|
||||
|
||||
<hr><a name="n11"></a>
|
||||
<a name="n11"></a><H2>23.3 The Ruby-to-C/C++ Mapping</H2>
|
||||
<H2><a name="Ruby_nn11"></a>26.3 The Ruby-to-C/C++ Mapping</H2>
|
||||
|
||||
|
||||
This section describes the basics of how SWIG maps C or C++
|
||||
declarations
|
||||
in your SWIG interface files to Ruby constructs.
|
||||
<a name="n12"></a>
|
||||
<a name="n12"></a><H3>23.3.1 Modules</H3>
|
||||
<H3><a name="Ruby_nn12"></a>26.3.1 Modules</H3>
|
||||
|
||||
|
||||
The SWIG <tt>%module</tt> directive specifies the name of the Ruby
|
||||
|
|
@ -463,13 +456,13 @@ global module,
|
|||
take care that the names of your constants, classes and methods don't
|
||||
conflict
|
||||
with any of Ruby's built-in names.
|
||||
<a name="n13"></a></p>
|
||||
<a name="n13"></a><H3>23.3.2 Functions</H3>
|
||||
|
||||
<H3><a name="Ruby_nn13"></a>26.3.2 Functions</H3>
|
||||
|
||||
|
||||
Global functions are wrapped as Ruby module methods. For example, given
|
||||
the SWIG interface file <tt>example.i</tt>:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>%module example<br><br>int fact(int n);<br></pre>
|
||||
</blockquote>
|
||||
|
|
@ -480,7 +473,7 @@ and C source file <tt>example.c</tt>:
|
|||
SWIG will generate a method <i>fact</i> in the <i>Example</i> module
|
||||
that
|
||||
can be used like so:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>irb</b>
|
||||
irb(main):001:0> <b>require 'example'</b>
|
||||
|
|
@ -489,8 +482,7 @@ irb(main):002:0> <b>Example.fact(4)</b>
|
|||
24
|
||||
</pre>
|
||||
</blockquote>
|
||||
<a name="n14"></a>
|
||||
<a name="n14"></a><H3>23.3.3 Variable Linking</H3>
|
||||
<H3><a name="Ruby_nn14"></a>26.3.3 Variable Linking</H3>
|
||||
|
||||
|
||||
C/C++ global variables are wrapped as a pair of singleton methods for
|
||||
|
|
@ -504,8 +496,7 @@ variables:
|
|||
</blockquote>
|
||||
<p>
|
||||
Now look at the Ruby interface:</p>
|
||||
<p></p>
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>irb</b>
|
||||
irb(main):001:0> <b>require 'Example'</b>
|
||||
|
|
@ -543,8 +534,7 @@ directive. For example:
|
|||
The <tt>%immutable</tt> directive stays in effect until it is
|
||||
explicitly
|
||||
disabled using <tt>%mutable</tt>.
|
||||
<a name="n15"></a>
|
||||
<a name="n15"></a><H3>23.3.4 Constants</H3>
|
||||
<H3><a name="Ruby_nn15"></a>26.3.4 Constants</H3>
|
||||
|
||||
|
||||
C/C++ constants are wrapped as module constants initialized to the
|
||||
|
|
@ -555,7 +545,7 @@ appropriate value. To create a constant, use <tt>#define</tt> or the
|
|||
</blockquote>
|
||||
Remember to use the :: operator in Ruby to get at these constant
|
||||
values, e.g.
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>irb</b>
|
||||
irb(main):001:0> <b>require 'Example'</b>
|
||||
|
|
@ -564,8 +554,7 @@ irb(main):002:0> <b>Example::PI</b>
|
|||
3.14159
|
||||
</pre>
|
||||
</blockquote>
|
||||
<a name="n16"></a>
|
||||
<a name="n16"></a><H3>23.3.5 Pointers</H3>
|
||||
<H3><a name="Ruby_nn16"></a>26.3.5 Pointers</H3>
|
||||
|
||||
|
||||
"Opaque" pointers to arbitrary C/C++ types (i.e. types that aren't
|
||||
|
|
@ -574,7 +563,7 @@ declared in your SWIG interface file) are wrapped as data objects. So,
|
|||
for
|
||||
example, consider a SWIG interface file containing only the
|
||||
declarations:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>Foo *get_foo();<br>void set_foo(Foo *foo);<br></pre>
|
||||
</blockquote>
|
||||
|
|
@ -587,15 +576,14 @@ internally generated Ruby class:
|
|||
</blockquote>
|
||||
A <tt>NULL</tt> pointer is always represented by the Ruby <tt>nil</tt>
|
||||
object.
|
||||
<a name="n17"></a>
|
||||
<a name="n17"></a><H3>23.3.6 Structures</H3>
|
||||
<H3><a name="Ruby_nn17"></a>26.3.6 Structures</H3>
|
||||
|
||||
|
||||
C/C++ structs are wrapped as Ruby classes, with accessor methods (i.e.
|
||||
"getters"
|
||||
and "setters") for all of the struct members. For example, this struct
|
||||
declaration:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>struct Vector {<br> double x, y;<br>};<br></pre>
|
||||
</blockquote>
|
||||
|
|
@ -603,7 +591,7 @@ gets wrapped as a <tt>Vector</tt> class, with Ruby instance methods <tt>x</tt>,
|
|||
<tt>x=</tt>, <tt>y</tt> and <tt>y=</tt>. These methods can be used to
|
||||
access
|
||||
structure data from Ruby as follows:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>irb</b>
|
||||
irb(main):001:0> <b>require 'Example'</b>
|
||||
|
|
@ -620,7 +608,7 @@ irb(main):004:0> <b>f.x</b>
|
|||
Similar access is provided for unions and the public data members of
|
||||
C++
|
||||
classes.</p>
|
||||
<p></p>
|
||||
|
||||
<p><tt>const</tt> members of a structure are read-only. Data members
|
||||
can also be
|
||||
forced to be read-only using the <tt>%immutable</tt> directive (in
|
||||
|
|
@ -654,7 +642,7 @@ produces a single accessor function like this:
|
|||
</blockquote>
|
||||
If you want to set an array member, you will need to supply a
|
||||
"memberin"
|
||||
typemap described in the <a href="#n24">section on typemaps</a>. As a
|
||||
typemap described in the <a href="#ruby_cpp_smart_pointers">section on typemaps</a>. As a
|
||||
special
|
||||
case, SWIG does generate code to set array members of type <tt>char</tt>
|
||||
(allowing you to store a Ruby string in the structure).
|
||||
|
|
@ -668,8 +656,7 @@ generates accessor functions such as this:
|
|||
<blockquote>
|
||||
<pre>Foo *Bar_f_get(Bar *b) {<br> return &b->f;<br>}<br><br>void Bar_f_set(Bar *b, Foo *val) {<br> b->f = *val;<br>}<br></pre>
|
||||
</blockquote>
|
||||
<a name="n18"></a>
|
||||
<a name="n18"></a><H3>23.3.7 C++ classes</H3>
|
||||
<H3><a name="Ruby_nn18"></a>26.3.7 C++ classes</H3>
|
||||
|
||||
|
||||
Like structs, C++ classes are wrapped by creating a new Ruby class of
|
||||
|
|
@ -681,8 +668,8 @@ methods,
|
|||
and public static member functions are wrapped as Ruby singleton
|
||||
methods. So,
|
||||
given the C++ class declaration:
|
||||
<p></p>
|
||||
<p></p>
|
||||
|
||||
|
||||
<blockquote>
|
||||
<pre>class List {<br>public:<br> List();<br> ~List();<br> int search(char *item);<br> void insert(char *item);<br> void remove(char *item);<br> char *get(int n);<br> int length;<br> static void print(List *l);<br>};<br></pre>
|
||||
</blockquote>
|
||||
|
|
@ -705,8 +692,7 @@ In Ruby, these functions are used as follows:
|
|||
<blockquote>
|
||||
<pre>require 'Example'<br><br>l = Example::List.new<br><br>l.insert("Ale")<br>l.insert("Stout")<br>l.insert("Lager")<br>Example.print(l)<br>l.length()<br>----- produces the following output <br>Lager<br>Stout<br>Ale<br>3<br></pre>
|
||||
</blockquote>
|
||||
<a name="n19"></a>
|
||||
<a name="n19"></a><H3>23.3.8 C++ Inheritance</H3>
|
||||
<H3><a name="Ruby_nn19"></a>26.3.8 C++ Inheritance</H3>
|
||||
|
||||
|
||||
The SWIG type-checker is fully aware of C++ inheritance. Therefore, if
|
||||
|
|
@ -822,8 +808,7 @@ will otherwise behave as though they inherit from both <tt>Base1</tt>
|
|||
and <tt>Base2</tt>
|
||||
(i.e. they exhibit <a href="http://c2.com/cgi/wiki?DuckTyping">"Duck
|
||||
Typing"</a>).
|
||||
<a name="n20"></a>
|
||||
<a name="n20"></a><H3>23.3.9 C++ Overloaded Functions</H3>
|
||||
<H3><a name="Ruby_nn20"></a>26.3.9 C++ Overloaded Functions</H3>
|
||||
|
||||
|
||||
C++ overloaded functions, methods, and constructors are mostly
|
||||
|
|
@ -878,9 +863,9 @@ which declarations appear
|
|||
in the input does not matter except in situations where ambiguity
|
||||
arises--in this case, the
|
||||
first declaration takes precedence.
|
||||
<p>Please refer to the <a href="SWIGPlus.html">"SWIG and C++"</a>
|
||||
<p>Please refer to the <a href="SWIGPlus.html#SWIGPlus">"SWIG and C++"</a>
|
||||
chapter for more information about overloading. <a name="n21"></a></p>
|
||||
<a name="n21"></a><H3>23.3.10 C++ Operators</H3>
|
||||
<H3><a name="Ruby_nn21"></a>26.3.10 C++ Operators</H3>
|
||||
|
||||
|
||||
For the most part, overloaded operators are handled automatically by
|
||||
|
|
@ -909,9 +894,8 @@ Now, in Ruby, you can do this:
|
|||
</blockquote>
|
||||
More details about wrapping C++ operators into Ruby operators is
|
||||
discussed in
|
||||
the <a href="#n39">section on operator overloading</a>.
|
||||
<a name="n22"></a>
|
||||
<a name="n22"></a><H3>23.3.11 C++ namespaces</H3>
|
||||
the <a href="#ruby_operator_overloading">section on operator overloading</a>.
|
||||
<H3><a name="Ruby_nn22"></a>26.3.11 C++ namespaces</H3>
|
||||
|
||||
|
||||
SWIG is aware of C++ namespaces, but namespace names do not appear in
|
||||
|
|
@ -946,8 +930,7 @@ For example, make the module name the same as the namespace and create
|
|||
extension modules for each namespace separately. If your program
|
||||
utilizes thousands of small deeply nested namespaces each with
|
||||
identical symbol names, well, then you get what you deserve.
|
||||
<a name="n23"></a>
|
||||
<a name="n23"></a><H3>23.3.12 C++ templates</H3>
|
||||
<H3><a name="Ruby_nn23"></a>26.3.12 C++ templates</H3>
|
||||
|
||||
|
||||
C++ templates don't present a huge problem for SWIG. However, in order
|
||||
|
|
@ -1000,10 +983,9 @@ float sum(const std::vector<float>& values);
|
|||
</blockquote>
|
||||
Obviously, there is a lot more to template wrapping than shown in these
|
||||
examples.
|
||||
More details can be found in the <a href="SWIGPlus.html">SWIG and C++</a>
|
||||
More details can be found in the <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a>
|
||||
chapter.
|
||||
<a name="n24"></a>
|
||||
<a name="n24"></a><H3>23.3.13 C++ Smart Pointers</H3>
|
||||
<H3><a name="ruby_cpp_smart_pointers"></a>26.3.13 C++ Smart Pointers</H3>
|
||||
|
||||
|
||||
In certain C++ programs, it is common to use classes that have been
|
||||
|
|
@ -1040,21 +1022,19 @@ simply use the <tt>__deref__()</tt> method. For example:
|
|||
<blockquote>
|
||||
<pre>irb(main):004:0> <b>f = p.__deref__()</b> # Returns underlying Foo *<br></pre>
|
||||
</blockquote>
|
||||
<a name="n25"></a>
|
||||
<a name="n25"></a><H3>23.3.14 Cross-Language Polymorphism</H3>
|
||||
<H3><a name="Ruby_nn25"></a>26.3.14 Cross-Language Polymorphism</H3>
|
||||
|
||||
|
||||
SWIG's Ruby module supports cross-language polymorphism (a.k.a. the
|
||||
"directors"
|
||||
feature) similar to that for SWIG's Python module. Rather than
|
||||
duplicate the
|
||||
information presented in the <a href="Python.html">Python</a> chapter,
|
||||
information presented in the <a href="Python.html#Python">Python</a> chapter,
|
||||
this
|
||||
secton just notes the differences that you need to be aware of when
|
||||
using this
|
||||
feature with Ruby.
|
||||
<a name="n26"></a>
|
||||
<a name="n26"></a><H4>23.3.14.1 Exception Unrolling</H4>
|
||||
<H4><a name="Ruby_nn26"></a>26.3.14.1 Exception Unrolling</H4>
|
||||
|
||||
|
||||
Whenever a C++ director class routes one of its virtual member function
|
||||
|
|
@ -1079,7 +1059,7 @@ Ruby exception
|
|||
is raised, it will be caught here and a C++ exception is raised in its
|
||||
place.
|
||||
<hr><a name="n27"></a>
|
||||
<a name="n27"></a><H2>23.4 Input and output parameters</H2>
|
||||
<H2><a name="Ruby_nn27"></a>26.4 Input and output parameters</H2>
|
||||
|
||||
|
||||
A common problem in some C programs is handling parameters passed as
|
||||
|
|
@ -1154,18 +1134,17 @@ In Ruby:
|
|||
<pre>r, c = Example.get_dimensions(m)<br></pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<a name="n28"></a>
|
||||
<a name="n28"></a><H2>23.5 Simple exception handling </H2>
|
||||
<H2><a name="Ruby_nn28"></a>26.5 Simple exception handling </H2>
|
||||
|
||||
|
||||
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 Features</a>
|
||||
chapter on <a href="Customization.html#Customization">Customization Features</a>
|
||||
contains more
|
||||
details, but suppose you have a C++ class like the following :
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<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>
|
||||
</blockquote>
|
||||
|
|
@ -1174,7 +1153,7 @@ out-of-bounds
|
|||
access, you might want to catch this in the Ruby extension by writing
|
||||
the
|
||||
following in an interface file:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<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>
|
||||
</blockquote>
|
||||
|
|
@ -1196,7 +1175,7 @@ functions
|
|||
named <tt>getitem</tt> and <tt>setitem</tt>.
|
||||
<p>Since SWIG's exception handling is user-definable, you are not
|
||||
limited to C++
|
||||
exception handling. See the chapter on <a href="Customization.html">Customization
|
||||
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>
|
||||
|
|
@ -1210,7 +1189,7 @@ Ruby exception classes, consult a Ruby reference such as <a
|
|||
href="http://www.rubycentral.com/book"><em>Programming Ruby</em></a>.
|
||||
</p>
|
||||
<hr><a name="n29"></a>
|
||||
<a name="n29"></a><H2>23.6 Typemaps</H2>
|
||||
<H2><a name="Ruby_nn29"></a>26.6 Typemaps</H2>
|
||||
|
||||
|
||||
This section describes how you can modify SWIG's default wrapping
|
||||
|
|
@ -1219,22 +1198,22 @@ for various C/C++ datatypes using the <tt>%typemap</tt> directive.
|
|||
This
|
||||
is an advanced topic that assumes familiarity with the Ruby C API as
|
||||
well
|
||||
as the material in the "<a href="Typemaps.html">Typemaps</a>" chapter.
|
||||
as the material in the "<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter.
|
||||
<p>Before proceeding, it should be stressed that typemaps are not a
|
||||
required part 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.
|
||||
<a name="n30"></a></p>
|
||||
<a name="n30"></a><H3>23.6.1 What is a typemap?</H3>
|
||||
|
||||
<H3><a name="Ruby_nn30"></a>26.6.1 What is a typemap?</H3>
|
||||
|
||||
|
||||
A typemap is nothing more than a code generation rule that is attached
|
||||
to a specific C datatype. For example, to convert integers from Ruby to
|
||||
C,
|
||||
you might define a typemap like this:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>%module example<br><br>%typemap(in) int {<br> $1 = (int) NUM2INT($input);<br> printf("Received an integer : %d\n",$1);<br>}<br><br>extern int fact(int n);<br></pre>
|
||||
</blockquote>
|
||||
|
|
@ -1254,7 +1233,7 @@ The <tt>$input</tt> variable is the input Ruby object.
|
|||
<p>When this example is compiled into a Ruby module, the following
|
||||
sample code:
|
||||
</p>
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>require 'example'<br><br>puts Example.fact(6)<br></pre>
|
||||
</blockquote>
|
||||
|
|
@ -1308,8 +1287,7 @@ follows (notice how the length parameter is omitted):
|
|||
<blockquote>
|
||||
<pre>puts Example.count('o','Hello World')<br>2<br></pre>
|
||||
</blockquote>
|
||||
<a name="n31"></a>
|
||||
<a name="n31"></a><H3>23.6.2 Ruby typemaps</H3>
|
||||
<H3><a name="Ruby_nn31"></a>26.6.2 Ruby typemaps</H3>
|
||||
|
||||
|
||||
The previous section illustrated an "in" typemap for converting Ruby
|
||||
|
|
@ -1363,16 +1341,15 @@ Ruby module:
|
|||
<blockquote>Initialize an argument to a value before any conversions
|
||||
occur.
|
||||
</blockquote>
|
||||
Examples of these typemaps appears in the <a href="#n34">section on
|
||||
Examples of these typemaps appears in the <a href="#ruby_typemap_examples">section on
|
||||
typemap
|
||||
examples</a>
|
||||
<a name="n32"></a>
|
||||
<a name="n32"></a><H3>23.6.3 Typemap variables</H3>
|
||||
<H3><a name="Ruby_nn32"></a>26.6.3 Typemap variables</H3>
|
||||
|
||||
|
||||
Within a typemap, a number of special variables prefaced with a <tt>$</tt>
|
||||
may appear. A full list of variables can be found in the "<a
|
||||
href="Typemaps.html">Typemaps</a>" chapter. This is a list of the most
|
||||
href="Typemaps.html#Typemaps">Typemaps</a>" chapter. This is a list of the most
|
||||
common
|
||||
variables:
|
||||
<p><tt>$1</tt>
|
||||
|
|
@ -1410,8 +1387,7 @@ so that their values can be properly assigned.
|
|||
<tt>$symname</tt>
|
||||
<blockquote>The Ruby name of the wrapper function being created.
|
||||
</blockquote>
|
||||
<a name="n33"></a>
|
||||
<a name="n33"></a><H3>23.6.4 Useful Functions</H3>
|
||||
<H3><a name="Ruby_nn33"></a>26.6.4 Useful Functions</H3>
|
||||
|
||||
|
||||
When you write a typemap, you usually have to work directly with Ruby
|
||||
|
|
@ -1422,21 +1398,19 @@ more can be found in <a href="http://www.rubycentral.com/book"><em>Programming
|
|||
Ruby</em></a>, by David Thomas
|
||||
and Andrew Hunt.)
|
||||
<p><a name="n34"></a></p>
|
||||
<a name="n34"></a><H4>23.6.4.1 C Datatypes to Ruby Objects</H4>
|
||||
<H4><a name="Ruby_nn34"></a>26.6.4.1 C Datatypes to Ruby Objects</H4>
|
||||
|
||||
|
||||
<blockquote>
|
||||
<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>
|
||||
</blockquote>
|
||||
<a name="n35"></a>
|
||||
<a name="n35"></a><H4>23.6.4.2 Ruby Objects to C Datatypes</H4>
|
||||
<H4><a name="Ruby_nn35"></a>26.6.4.2 Ruby Objects to C Datatypes</H4>
|
||||
|
||||
|
||||
<blockquote>
|
||||
<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>
|
||||
</blockquote>
|
||||
<a name="n36"></a>
|
||||
<a name="n36"></a><H4>23.6.4.3 Macros for VALUE</H4>
|
||||
<H4><a name="Ruby_nn36"></a>26.6.4.3 Macros for VALUE</H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1451,8 +1425,7 @@ and Andrew Hunt.)
|
|||
<blockquote>capacity of the Ruby array</blockquote>
|
||||
<tt>RARRAY(arr)->ptr</tt>
|
||||
<blockquote>pointer to array storage</blockquote>
|
||||
<a name="n37"></a>
|
||||
<a name="n37"></a><H4>23.6.4.4 Exceptions</H4>
|
||||
<H4><a name="Ruby_nn37"></a>26.6.4.4 Exceptions</H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1510,8 +1483,7 @@ interpreted as with <tt>printf()</tt>.
|
|||
if Ruby was invoked with the <tt>-w</tt> flag. The given format string
|
||||
<i>fmt</i> and remaining arguments are interpreted as with <tt>printf()</tt>.
|
||||
</blockquote>
|
||||
<a name="n38"></a>
|
||||
<a name="n38"></a><H4>23.6.4.5 Iterators</H4>
|
||||
<H4><a name="Ruby_nn38"></a>26.6.4.5 Iterators</H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1544,15 +1516,13 @@ value)</tt>
|
|||
<tt>void rb_throw(const char *tag, VALUE value)</tt>
|
||||
<blockquote> Equivalent to Ruby's <tt>throw</tt>.
|
||||
</blockquote>
|
||||
<a name="n39"></a>
|
||||
<a name="n39"></a><H3>23.6.5 Typemap Examples</H3>
|
||||
<H3><a name="ruby_typemap_examples"></a>26.6.5 Typemap Examples</H3>
|
||||
|
||||
|
||||
This section includes a few examples of typemaps. For more examples,
|
||||
you
|
||||
might look at the examples in the <tt>Example/ruby</tt> directory.
|
||||
<a name="n40"></a>
|
||||
<a name="n40"></a><H3>23.6.6 Converting a Ruby array to a char **</H3>
|
||||
<H3><a name="Ruby_nn40"></a>26.6.6 Converting a Ruby array to a char **</H3>
|
||||
|
||||
|
||||
A common problem in many C programs is the processing of command line
|
||||
|
|
@ -1560,15 +1530,15 @@ arguments, which are usually passed in an array of <tt>NULL</tt>
|
|||
terminated
|
||||
strings. The following SWIG interface file allows a Ruby Array instance
|
||||
to be used as a <tt>char **</tt> object.
|
||||
<p></p>
|
||||
<p></p>
|
||||
|
||||
|
||||
<blockquote>
|
||||
<pre>%module argv<br><br>// This tells SWIG to treat char ** as a special case<br>%typemap(in) char ** {<br> /* Get the length of the array */<br> int size = RARRAY($input)->len; <br> int i;<br> $1 = (char **) malloc((size+1)*sizeof(char *));<br> /* Get the first element in memory */<br> VALUE *ptr = RARRAY($input)->ptr; <br> for (i=0; i < size; i++, ptr++)<br> /* Convert Ruby Object String to char* */<br> $1[i]= STR2CSTR(*ptr); <br> $1[i]=NULL; /* End of list */<br>}<br><br>// This cleans up the char ** array created before <br>// the function call<br><br>%typemap(freearg) char ** {<br> free((char *) $1);<br>}<br><br>// Now a test function<br>%inline %{<br>int print_args(char **argv) {<br> int i = 0;<br> while (argv[i]) {<br> printf("argv[%d] = %s\n", i,argv[i]);<br> i++;<br> }<br> return i;<br>}<br>%}<br><br></pre>
|
||||
</blockquote>
|
||||
When this module is compiled, the wrapped C function now operates as
|
||||
follows :
|
||||
<p></p>
|
||||
<p></p>
|
||||
|
||||
|
||||
<blockquote>
|
||||
<pre>require 'Argv'<br>Argv.print_args(["Dave","Mike","Mary","Jane","John"])<br>argv[0] = Dave<br>argv[1] = Mike<br>argv[2] = Mary<br>argv[3] = Jane<br>argv[4] = John<br></pre>
|
||||
</blockquote>
|
||||
|
|
@ -1580,7 +1550,7 @@ 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. <a name="n41"></a>
|
||||
<a name="n41"></a><H3>23.6.7 Collecting arguments in a hash</H3>
|
||||
<H3><a name="Ruby_nn41"></a>26.6.7 Collecting arguments in a hash</H3>
|
||||
|
||||
|
||||
Ruby's solution to the "keyword arguments" capability of some other
|
||||
|
|
@ -1736,8 +1706,7 @@ uses
|
|||
the extension, can be found in the <tt>Examples/ruby/hashargs</tt>
|
||||
directory
|
||||
of the SWIG distribution.
|
||||
<a name="n42"></a>
|
||||
<a name="n42"></a><H3>23.6.8 Pointer handling</H3>
|
||||
<H3><a name="Ruby_nn42"></a>26.6.8 Pointer handling</H3>
|
||||
|
||||
|
||||
Occasionally, it might be necessary to convert pointer values that have
|
||||
|
|
@ -1797,8 +1766,7 @@ typemap variable <tt>$1_descriptor</tt>. For example:
|
|||
<blockquote>
|
||||
<pre>%typemap(in) Foo * {<br> SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);<br>}<br></pre>
|
||||
</blockquote>
|
||||
<a name="n43"></a>
|
||||
<a name="n43"></a><H4>23.6.8.1 Ruby Datatype Wrapping</H4>
|
||||
<H4><a name="Ruby_nn43"></a>26.6.8.1 Ruby Datatype Wrapping</H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1822,8 +1790,7 @@ from the data object
|
|||
<i>obj</i> and assigns that pointer to <i>ptr</i>.
|
||||
</blockquote>
|
||||
<hr>
|
||||
<a name="n44"></a>
|
||||
<a name="n44"></a><H2>23.7 Operator overloading</H2>
|
||||
<H2><a name="ruby_operator_overloading"></a>26.7 Operator overloading</H2>
|
||||
|
||||
|
||||
SWIG allows operator overloading with, by using the <tt>%extend</tt>
|
||||
|
|
@ -1838,8 +1805,7 @@ 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>.
|
||||
<a name="n45"></a>
|
||||
<a name="n45"></a><H3>23.7.1 Example: STL Vector to Ruby Array</H3>
|
||||
<H3><a name="Ruby_nn45"></a>26.7.1 Example: STL Vector to Ruby Array</H3>
|
||||
|
||||
|
||||
<em><b>FIXME: This example is out of place here!</b></em>
|
||||
|
|
@ -1855,7 +1821,7 @@ construct this type of macro/typemap and should give insight into
|
|||
constructing
|
||||
similar typemaps for other STL structures:
|
||||
</p>
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>%define PTR_VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)<br>%typemap(ruby, 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(ruby, 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>
|
||||
</blockquote>
|
||||
|
|
@ -1864,19 +1830,20 @@ preprocessor step
|
|||
to determine the actual object from the class name.
|
||||
<p>To use the macro with a class Foo, the following is used:
|
||||
</p>
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>PTR_VECTOR_TO_RUBY_ARRAY(vector<foo *="">, Foo)<br></foo></pre>
|
||||
<pre>PTR_VECTOR_TO_RUBY_ARRAY(vector<foo *="">, Foo)<br></pre>
|
||||
</blockquote>
|
||||
It is also possible to create a STL vector of Ruby objects:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>%define RUBY_ARRAY_TO_PTR_VECTOR(vectorclassname, classname)<br>%typemap(ruby, in) vectorclassname &, const vectorclassname & {<br> Check_Type($input, T_ARRAY);<br> vectorclassname *vec = new vectorclassname;<br> int len = RARRAY($input)->len;<br> for (int i=0; i!=len; i++) {<br> VALUE inst = rb_ary_entry($input, i);<br> //The following _should_ work but doesn't on HPUX<br> // Check_Type(inst, T_DATA);<br> classname *element = NULL;<br> Data_Get_Struct(inst, classname, element);<br> vec->push_back(element);<br> }<br> $1 = vec;<br>}<br><br>%typemap(ruby, freearg) vectorclassname &, const vectorclassname & {<br> delete $1;<br>}<br>%enddef<br></pre>
|
||||
</blockquote>
|
||||
|
||||
It is also possible to create a Ruby array from a vector of static data
|
||||
types:
|
||||
<p></p>
|
||||
<pre><blockquote>
|
||||
|
||||
<blockquote><pre>
|
||||
%define VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)
|
||||
%typemap(ruby, out) vectorclassname &, const vectorclassname & {
|
||||
VALUE arr = rb_ary_new2($1->size());
|
||||
|
|
@ -1893,16 +1860,14 @@ types:
|
|||
$result = arr;
|
||||
}
|
||||
%enddef
|
||||
</blockquote></pre>
|
||||
<a name="n46"></a>
|
||||
<a name="n46"></a><H2>23.8 Advanced Topics</H2>
|
||||
</pre></blockquote>
|
||||
<H2><a name="Ruby_nn46"></a>26.8 Advanced Topics</H2>
|
||||
|
||||
|
||||
<a name="n47"></a>
|
||||
<a name="n47"></a><H3>23.8.1 Creating Multi-Module Packages</H3>
|
||||
<H3><a name="Ruby_nn47"></a>26.8.1 Creating Multi-Module Packages</H3>
|
||||
|
||||
|
||||
The chapter on <a href="Advanced.html">Advanced Topics</a> discusses
|
||||
The chapter on <a href="Advanced.html#Advanced">Advanced Topics</a> discusses
|
||||
the basics
|
||||
of creating multi-module extensions with SWIG, and in particular
|
||||
the considerations for sharing runtime type information among the
|
||||
|
|
@ -1924,7 +1889,7 @@ option so that
|
|||
the runtime library code is omitted from the wrapper files. We'll start
|
||||
by building
|
||||
the <b>Shape</b> extension module:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>swig -c++ -ruby -c shape.i</b>
|
||||
</pre>
|
||||
|
|
@ -1933,14 +1898,14 @@ SWIG generates a wrapper file named <tt>shape_wrap.cxx</tt>. To
|
|||
compile this
|
||||
into a dynamically loadable extension for Ruby, prepare an <tt>extconf.rb</tt>
|
||||
script using this template:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>require 'mkmf'<br><br># Since the SWIG runtime support library for Ruby (libswigrb.so)<br># depends on the Ruby library, make sure it's in the list<br># of libraries.<br>$libs = append_library($libs, Config::CONFIG['RUBY_INSTALL_NAME'])<br><br># Now add the SWIG runtime support library<br>have_library('swigrb', 'SWIG_InitRuntime')<br><br># Create the makefile<br>create_makefile('shape')<br></pre>
|
||||
</blockquote>
|
||||
Run this script to create a <tt>Makefile</tt> and then type <tt>make</tt>
|
||||
to
|
||||
build the shared library:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>ruby extconf.rb</b>
|
||||
checking for SWIG_InitRuntime() in -lswigrb... yes
|
||||
|
|
@ -1974,7 +1939,7 @@ to create a platform-specific <tt>Makefile</tt> for the extension;
|
|||
Once you've built both of these extension modules, you can test them
|
||||
interactively in IRB to confirm that the <tt>Shape</tt> and <tt>Circle</tt>
|
||||
modules are properly loaded and initialized:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>$ <b>irb</b>
|
||||
irb(main):001:0> <b>require 'shape'</b>
|
||||
|
|
@ -1989,8 +1954,7 @@ irb(main):005:0> <b>c.getX()</b>
|
|||
5.0
|
||||
</pre>
|
||||
</blockquote>
|
||||
<a name="n48"></a>
|
||||
<a name="n48"></a><H3>23.8.2 Defining Aliases</H3>
|
||||
<H3><a name="Ruby_nn48"></a>26.8.2 Defining Aliases</H3>
|
||||
|
||||
|
||||
It's a fairly common practice in the Ruby built-ins and standard
|
||||
|
|
@ -2002,14 +1966,14 @@ 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></p>
|
||||
|
||||
<blockquote>
|
||||
<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>
|
||||
</blockquote>
|
||||
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></p>
|
||||
|
||||
<blockquote>
|
||||
<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>
|
||||
</blockquote>
|
||||
|
|
@ -2032,11 +1996,11 @@ wrapper code that's usually associated with added methods like our
|
|||
"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
|
||||
apply (see the chapter on <a href="Customization.html#Customization">"Customization
|
||||
Features"</a>)
|
||||
for more details).
|
||||
<a name="n49"></a></p>
|
||||
<a name="n49"></a><H3>23.8.3 Predicate Methods</H3>
|
||||
|
||||
<H3><a name="Ruby_nn49"></a>26.8.3 Predicate Methods</H3>
|
||||
|
||||
|
||||
Predicate methods in Ruby are those which return either <tt>true</tt>
|
||||
|
|
@ -2068,7 +2032,7 @@ A better solution is to instead use the <tt>%predicate</tt> directive
|
|||
to SWIG's Ruby module) to designate certain methods as predicate
|
||||
methods.
|
||||
For the previous example, this would look like:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>%predicate is_it_safe();<br><br>int is_it_safe();<br></pre>
|
||||
</blockquote>
|
||||
|
|
@ -2082,10 +2046,9 @@ 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
|
||||
of features apply (see the chapter on <a href="Customization.html#Customization">"Customization
|
||||
Features"</a>) for more details).
|
||||
<a name="n50"></a>
|
||||
<a name="n50"></a><H3>23.8.4 Specifying Mixin Modules</H3>
|
||||
<H3><a name="Ruby_nn50"></a>26.8.4 Specifying Mixin Modules</H3>
|
||||
|
||||
|
||||
The Ruby language doesn't support multiple inheritance, but it does
|
||||
|
|
@ -2095,14 +2058,14 @@ method.
|
|||
For example, if you have a Ruby class that defines an <em>each</em>
|
||||
instance
|
||||
method, e.g.
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>class Set<br> def initialize<br> @members = []<br> end<br> <br> def each<br> @members.each { |m| yield m }<br> end<br>end<br></pre>
|
||||
</blockquote>
|
||||
then you can mix-in Ruby's <tt>Enumerable</tt> module to easily add a
|
||||
lot
|
||||
of functionality to your class:
|
||||
<p></p>
|
||||
|
||||
<blockquote>
|
||||
<pre>class Set<br> <b>include Enumerable</b>
|
||||
|
||||
|
|
@ -2133,10 +2096,9 @@ module names to the <tt>%mixin</tt> directive, e.g.
|
|||
Note that the <tt>%mixin</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
|
||||
of features apply (see the chapter on <a href="Customization.html#Customization">"Customization
|
||||
Features"</a>) for more details).
|
||||
<a name="n51"></a>
|
||||
<a name="n51"></a><H3>23.8.5 Interacting with Ruby's Garbage Collector</H3>
|
||||
<H3><a name="Ruby_nn51"></a>26.8.5 Interacting with Ruby's Garbage Collector</H3>
|
||||
|
||||
|
||||
<b>This section is still unfinished!</b>
|
||||
|
|
@ -2163,8 +2125,8 @@ models
|
|||
a zoo and the animals in the zoo:
|
||||
</p>
|
||||
<blockquote>
|
||||
<pre>%module zoo<br><br>%{<br>#include <string>
|
||||
#include <vector>
|
||||
<pre>%module zoo<br><br>%{<br>#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "zoo.h"
|
||||
%}
|
||||
|
|
@ -2185,8 +2147,7 @@ public:
|
|||
class Zoo
|
||||
{
|
||||
protected:
|
||||
std::vector<animal
|
||||
*=""> animals;<br> <br>public:<br> // Construct an empty zoo<br> Zoo() {}<br> <br> // Add a new animal to the zoo<br> void addAnimal(Animal* animal) {<br> animals.push_back(animal); <br> }<br> <br> // Return the number of animals in the zoo<br> size_t getNumAnimals() const {<br> return animals.size(); <br> }<br> <br> // Return a pointer to the ith animal<br> Animal* getAnimal(size_t i) const {<br> return animals[i]; <br> }<br>};<br><br></animal></vector></string></pre>
|
||||
std::vector<animal *=""> animals;<br> <br>public:<br> // Construct an empty zoo<br> Zoo() {}<br> <br> // Add a new animal to the zoo<br> void addAnimal(Animal* animal) {<br> animals.push_back(animal); <br> }<br> <br> // Return the number of animals in the zoo<br> size_t getNumAnimals() const {<br> return animals.size(); <br> }<br> <br> // Return a pointer to the ith animal<br> Animal* getAnimal(size_t i) const {<br> return animals[i]; <br> }<br>};<br><br></pre>
|
||||
</blockquote>
|
||||
Basically, a <tt>Zoo</tt> is modeled as a "container" for animals. And
|
||||
we can
|
||||
|
|
@ -2247,8 +2208,8 @@ of the
|
|||
Ruby instances associated with those C++ <tt>Animal</tt> objects:
|
||||
</p>
|
||||
<blockquote>
|
||||
<pre>void Zoo_markfunc(void *ptr)<br>{<br> Animal *cppAnimal;<br> VALUE rubyAnimal;<br> Zoo *zoo;<br> <br> zoo = static_cast<zoo
|
||||
*="">(ptr);<br> for (size_t i = 0; i < zoo->getNumAnimals(); i++) {<br> cppAnimal = zoo->getAnimal(i);<br> rubyAnimal = SWIG_RubyInstanceFor(cppAnimal);<br> rb_gc_mark(rubyAnimal);<br> }<br>}<br></zoo></pre>
|
||||
<pre>void Zoo_markfunc(void *ptr)<br>{<br> Animal *cppAnimal;<br> VALUE rubyAnimal;<br> Zoo *zoo;<br> <br> zoo = static_cast<zoo
|
||||
*="">(ptr);<br> for (size_t i = 0; i < zoo->getNumAnimals(); i++) {<br> cppAnimal = zoo->getAnimal(i);<br> rubyAnimal = SWIG_RubyInstanceFor(cppAnimal);<br> rb_gc_mark(rubyAnimal);<br> }<br>}<br></pre>
|
||||
</blockquote>
|
||||
<em>SWIG_RubyInstanceFor() is an imaginary function that takes a
|
||||
pointer
|
||||
|
|
@ -2269,7 +2230,7 @@ are
|
|||
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 Features"</a>)
|
||||
<a href="Customization.html#Customization">"Customization Features"</a>)
|
||||
for more details).
|
||||
<hr>
|
||||
<address>SWIG 1.3 - Last Modified : $Date$</address>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue