From: <gg...@us...> - 2007-05-03 05:51:17
|
Revision: 9757 http://swig.svn.sourceforge.net/swig/?rev=9757&view=rev Author: gga73 Date: 2007-05-02 22:51:15 -0700 (Wed, 02 May 2007) Log Message: ----------- Added autodoc documentation to Ruby. Made the web page use the proper stylesheet for each section. Modified Paths: -------------- trunk/Doc/Manual/Ruby.html Modified: trunk/Doc/Manual/Ruby.html =================================================================== --- trunk/Doc/Manual/Ruby.html 2007-05-03 04:33:23 UTC (rev 9756) +++ trunk/Doc/Manual/Ruby.html 2007-05-03 05:51:15 UTC (rev 9757) @@ -1,15 +1,15 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> - - - <title>SWIG and Ruby</title> + + <link rel="stylesheet" type="text/css" href="style.css"> + </head> - <body style="background-color: rgb(255, 255, 255);"> +<body style="background-color: rgb(255, 255, 255);"> <h1><a name="Ruby"></a>30 SWIG and Ruby</h1> @@ -22,3971 +22,3301 @@ <li><a href="#Ruby_nn3">Running SWIG</a> </li> - <li><a href="#Ruby_nn4">Getting the right header files</a> - </li> - <li><a href="#Ruby_nn5">Compiling a dynamic module</a> - </li> + + <li><a href="#Ruby_nn4">Getting the right +header files</a> </li> + + <li><a href="#Ruby_nn5">Compiling a dynamic +module</a> </li> + <li><a href="#Ruby_nn6">Using your module</a> </li> + <li><a href="#Ruby_nn7">Static linking</a> </li> - <li><a href="#Ruby_nn8">Compilation of C++ extensions</a> - </li> + + <li><a href="#Ruby_nn8">Compilation of C++ +extensions</a> </li> + </ul> </li> - <li><a href="#Ruby_nn9">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="#Ruby_nn10">Running SWIG from Developer Studio</a> - </li> + <li><a href="#Ruby_nn10">Running SWIG from +Developer Studio</a> </li> + </ul> </li> + <li><a href="#Ruby_nn11">The Ruby-to-C/C++ Mapping</a> <ul> - <li><a href="#Ruby_nn12">Modules</a> - </li> - <li><a href="#Ruby_nn13">Functions</a> - </li> + <li><a href="#Ruby_nn12">Modules</a> </li> + + <li><a href="#Ruby_nn13">Functions</a> </li> + <li><a href="#Ruby_nn14">Variable Linking</a> </li> - <li><a href="#Ruby_nn15">Constants</a> - </li> - <li><a href="#Ruby_nn16">Pointers</a> - </li> - <li><a href="#Ruby_nn17">Structures</a> - </li> + + <li><a href="#Ruby_nn15">Constants</a> </li> + + <li><a href="#Ruby_nn16">Pointers</a> </li> + + <li><a href="#Ruby_nn17">Structures</a> </li> + <li><a href="#Ruby_nn18">C++ classes</a> </li> + <li><a href="#Ruby_nn19">C++ Inheritance</a> </li> - <li><a href="#Ruby_nn20">C++ Overloaded Functions</a> - </li> + + <li><a href="#Ruby_nn20">C++ Overloaded +Functions</a> </li> + <li><a href="#Ruby_nn21">C++ Operators</a> </li> + <li><a href="#Ruby_nn22">C++ namespaces</a> </li> + <li><a href="#Ruby_nn23">C++ templates</a> </li> + <li><a href="#Ruby_nn24">C++ Smart Pointers</a> </li> - <li><a href="#Ruby_nn25">Cross-Language Polymorphism</a> + + <li><a href="#Ruby_nn25">Cross-Language +Polymorphism</a> <ul> - <li><a href="#Ruby_nn26">Exception Unrolling</a> - </li> + <li><a href="#Ruby_nn26">Exception +Unrolling</a> </li> + </ul> </li> + </ul> </li> + <li><a href="#Ruby_nn27">Naming</a> <ul> <li><a href="#Ruby_nn28">Defining Aliases</a> </li> + <li><a href="#Ruby_nn29">Predicate Methods</a> </li> + <li><a href="#Ruby_nn30">Bang Methods</a> </li> + <li><a href="#Ruby_nn31">Getters and Setters</a> </li> + </ul> </li> - <li><a href="#Ruby_nn32">Input and output parameters</a> - </li> - <li><a href="#Ruby_nn33">Exception handling </a> + + <li><a href="#Ruby_nn32">Input and output +parameters</a> </li> + + <li><a href="#Ruby_nn33">Exception handling </a> <ul> - <li><a href="#Ruby_nn34">Using the %exception directive </a> - </li> + <li><a href="#Ruby_nn34">Using the %exception +directive </a> </li> + <li><a href="#Ruby_nn35">Raising exceptions </a> </li> + <li><a href="#Ruby_nn36">Exception classes </a> </li> + </ul> </li> + <li><a href="#Ruby_nn37">Typemaps</a> <ul> <li><a href="#Ruby_nn38">What is a typemap?</a> </li> + <li><a href="#Ruby_nn39">Ruby typemaps</a> </li> + <li><a href="#Ruby_nn40">Typemap variables</a> </li> + <li><a href="#Ruby_nn41">Useful Functions</a> <ul> - <li><a href="#Ruby_nn42">C Datatypes to Ruby Objects</a> - </li> - <li><a href="#Ruby_nn43">Ruby Objects to C Datatypes</a> - </li> + <li><a href="#Ruby_nn42">C Datatypes to +Ruby Objects</a> </li> + + <li><a href="#Ruby_nn43">Ruby Objects to C +Datatypes</a> </li> + <li><a href="#Ruby_nn44">Macros for VALUE</a> </li> + <li><a href="#Ruby_nn45">Exceptions</a> </li> + <li><a href="#Ruby_nn46">Iterators</a> </li> + </ul> </li> + <li><a href="#Ruby_nn47">Typemap Examples</a> </li> - <li><a href="#Ruby_nn48">Converting a Ruby array to a char **</a> + + <li><a href="#Ruby_nn48">Converting a Ruby +array to a char **</a> </li> + + <li><a href="#Ruby_nn49">Collecting arguments +in a hash</a> </li> + + <li><a href="#Ruby_nn50">Pointer handling</a> + <ul> + + <li><a href="#Ruby_nn51">Ruby Datatype +Wrapping</a> </li> + + </ul> + </li> - <li><a href="#Ruby_nn49">Collecting arguments in a hash</a> + + <li><a href="#Ruby_nn52">Example: STL Vector +to Ruby Array</a></li> + + </ul> + + </li> + + <li><a href="#Ruby_nn65">Docstring +Features</a> + <ul> + + <li><a href="#Ruby_nn66">Module +docstring</a> </li> - <li><a href="#Ruby_nn50">Pointer handling</a> + + <li><a href="#Ruby_nn67">%feature("autodoc")</a> <ul> - <li><a href="#Ruby_nn51">Ruby Datatype Wrapping</a> + <li><a href="#Ruby_nn68">%feature("autodoc", +"0")</a> </li> + + <li><a href="#Ruby_nn69">%feature("autodoc", +"1")</a> + </li> + + <li><a href="#Ruby_nn70">%feature("autodoc", +"2")</a> + </li> + + <li><a href="#Ruby_nn71">%feature("autodoc", +"3")</a> + </li> + + <li><a href="#Ruby_nn72">%feature("autodoc", +"docstring")</a> + </li> + </ul> </li> - <li><a href="#Ruby_nn52">Example: STL Vector to Ruby Array</a> - </li> + + <li><a href="#Ruby_nn73">%feature("docstring")</a></li> + </ul> </li> + <li><a href="#Ruby_nn53">Advanced Topics</a> <ul> <li><a href="#Ruby_nn54">Operator overloading</a> </li> - <li><a href="#Ruby_nn55">Creating Multi-Module Packages</a> - </li> - <li><a href="#Ruby_nn56">Specifying Mixin Modules</a> - </li> + + <li><a href="#Ruby_nn55">Creating Multi-Module +Packages</a> </li> + + <li><a href="#Ruby_nn56">Specifying Mixin +Modules</a> </li> + </ul> </li> + <li><a href="#Ruby_nn57">Memory Management</a> <ul> - <li><a href="#Ruby_nn58">Mark and Sweep Garbage Collector </a> - </li> + <li><a href="#Ruby_nn58">Mark and Sweep +Garbage Collector </a> </li> + <li><a href="#Ruby_nn59">Object Ownership</a> </li> + <li><a href="#Ruby_nn60">Object Tracking</a> </li> + <li><a href="#Ruby_nn61">Mark Functions</a> </li> - <li><a href="#Ruby_nn62">Free Functions</a> - </li> + + <li><a href="#Ruby_nn62">Free Functions</a></li> + <li><a href="#Ruby_nn63">Embedded Ruby and the C++ Stack</a></li> + </ul> </li> + </ul> </div> <!-- INDEX --> - - - <p>This chapter describes SWIG's support of Ruby.</p> <h2><a name="Ruby_nn2"></a>30.1 Preliminaries</h2> +<p> SWIG 1.3 is known to work with Ruby versions 1.6 and later. +Given the choice, you should use the latest stable version of Ruby. You +should also determine if your system supports shared libraries and +dynamic loading. SWIG will work with or without dynamic loading, but +the compilation process will vary. </p> +<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">SWIG Basics</a>" +chapter. It is also assumed that the reader has a basic understanding +of Ruby. </p> - -<p> - SWIG 1.3 is known to work with Ruby versions 1.6 and later. Given the choice, - you should use the latest stable version of Ruby. You should also determine if - your system supports shared libraries and dynamic loading. SWIG will work with - or without dynamic loading, but the compilation process will vary. - </p> - - -<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">SWIG - Basics</a>" chapter. It is also assumed that the reader has a basic - understanding of Ruby. - </p> - <h3><a name="Ruby_nn3"></a>30.1.1 Running SWIG</h3> +<p> To build a Ruby module, run SWIG using the <tt>-ruby</tt> +option:</p> - - -<p> - To build a Ruby module, run SWIG using the <tt>-ruby</tt> option:</p> - - -<div class="code"> - +<div class="code shell"> <pre>$ <b>swig -ruby example.i</b> </pre> - </div> +</div> - -<p> - If building a C++ extension, add the <tt>-c++</tt> option: - </p> +<p> If building a C++ extension, add the <tt>-c++</tt> +option: </p> - -<div class="code"> - +<div class="code shell"> <pre>$ <b>swig -c++ -ruby example.i</b> </pre> - </div> +</div> - -<p> - This creates a file <tt>example_wrap.c</tt> (<tt>example_wrap.cxx</tt> if - compiling a C++ extension) that contains all of the code needed to 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. - </p> +<p> This creates a file <tt>example_wrap.c</tt> (<tt>example_wrap.cxx</tt> +if compiling a C++ extension) that contains all of the code needed to +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. </p> -<h3><a name="Ruby_nn4"></a>30.1.2 Getting the right header files</h3> +<h3><a name="Ruby_nn4"></a>30.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> - 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> - - -<div class="code"> - +<div class="code shell diagram"> <pre>/usr/local/lib/ruby/1.6/i686-linux/ruby.h<br></pre> - </div> +</div> - -<p> - The exact location may vary on your machine, but the above location is typical. - If you are not entirely sure where Ruby is installed, you can run Ruby to find - out. For example: - </p> +<p> The exact location may vary on your machine, but the above +location is typical. If you are not entirely sure where Ruby is +installed, you can run Ruby to find out. For example: </p> - -<div class="code"> - +<div class="code shell"> <pre>$ <b>ruby -e 'puts $:.join("\n")'</b><br>/usr/local/lib/ruby/site_ruby/1.6 /usr/local/lib/ruby/site_ruby/1.6/i686-linux<br>/usr/local/lib/ruby/site_ruby /usr/local/lib/ruby/1.6 /usr/local/lib/ruby/1.6/i686-linux .<br> </pre> - </div> +</div> -<h3><a name="Ruby_nn5"></a>30.1.3 Compiling a dynamic module</h3> +<h3><a name="Ruby_nn5"></a>30.1.3 Compiling a +dynamic module</h3> +<p> Ruby extension modules are typically compiled into shared +libraries that the interpreter loads dynamically at runtime. Since the +exact commands for 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> - Ruby extension modules are typically compiled into shared libraries that the - interpreter loads dynamically at runtime. Since the exact commands for 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> - - <ol> - <li> - - <p>Create a file called <tt>extconf.rb</tt> that looks like the following:</p> + <li> + <p>Create a file called <tt>extconf.rb</tt> that +looks like the following:</p> - - <div class="code"> - + <div class="code targetlang"> <pre>require 'mkmf'<br>create_makefile('example')<br></pre> - </div> + </div> - </li> + </li> - <li> - + <li> <p>Type the following to build the extension:</p> - - <div class="code"> - + <div class="code shell"> <pre>$ <b>ruby extconf.rb</b><br>$ <b>make</b><br>$ <b>make install</b> </pre> - </div> + </div> - </li> + </li> - </ol> - -<p> - Of course, there is the problem that mkmf does not work correctly on all - platforms, e.g, HPUX. If you need to add your own make rules to the file that <tt>extconf.rb</tt> - produces, you can add this: - </p> +<p> Of course, there is the problem that mkmf does not work +correctly on all platforms, e.g, HPUX. If you need to add your own make +rules to the file that <tt>extconf.rb</tt> produces, you +can add this: </p> - -<div class="code"> - +<div class="code targetlang"> <pre>open("Makefile", "a") { |mf|<br> puts <<EOM<br> # Your make rules go here<br> EOM<br>}<br></pre> - </div> +</div> - -<p> - to the end of the <tt>extconf.rb</tt> file. If for some reason you don't want - to use the standard approach, you'll need to determine the correct compiler and - linker flags for your build platform. For example, a typical sequence of - commands for the Linux operating system would look something like this: - </p> +<p> to the end of the <tt>extconf.rb</tt> file. If +for some reason you don't want to use the standard approach, you'll +need to determine the correct compiler and linker flags for your build +platform. For example, a typical sequence of commands for the Linux +operating system would look something like this: </p> - -<div class="code"> - +<div class="code shell"> <pre>$ <b>swig -ruby example.i</b><br>$ <b>gcc -c example.c</b><br>$ <b>gcc -c example_wrap.c -I/usr/local/lib/ruby/1.6/i686-linux</b> <br>$ <b>gcc -shared example.o example_wrap.o -o example.so</b> </pre> - </div> +</div> - -<p> - For other platforms it may be necessary to compile with the <tt>-fPIC</tt> option - to generate position-independent code. If in doubt, consult the manual pages - for your compiler and linker to determine the correct set of options. You might - also check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> - for additional information. - </p> +<p> For other platforms it may be necessary to compile with the <tt>-fPIC</tt> +option to generate position-independent code. If in doubt, consult the +manual pages for your compiler and linker to determine the correct set +of options. You might also check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> +for additional information. </p> - -<p> - <a name="n6"></a> - </p> +<p> <a name="n6"></a> </p> -<h3><a name="Ruby_nn6"></a>30.1.4 Using your module</h3> +<h3><a name="Ruby_nn6"></a>30.1.4 Using your +module</h3> +<p> 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: </p> - - -<p> - 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: - </p> - - -<div class="code"> - +<div class="code targetlang"> <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> - </div> +</div> - -<p> - 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: - </p> +<p> 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: </p> - <div class="code"> - <pre>%module example<br></pre> - </div> +</div> - -<p> - will result in an extension module using the feature name "example" and Ruby - module name "Example". - </p> +<p> will result in an extension module using the feature name +"example" and Ruby module name "Example". </p> -<h3><a name="Ruby_nn7"></a>30.1.5 Static linking</h3> +<h3><a name="Ruby_nn7"></a>30.1.5 Static +linking</h3> +<p> An alternative approach to dynamic linking is to rebuild the +Ruby interpreter with your extension module added to it. In the past, +this approach was sometimes necessary due to limitations in dynamic +loading support on certain machines. However, the situation has +improved greatly over the last few years and you should not consider +this approach unless there is really no other option. </p> +<p>The usual procedure for adding a new module to Ruby involves +finding the Ruby source, adding an entry to the <tt>ext/Setup</tt> +file, adding your directory to the list of extensions in the file, and +finally rebuilding Ruby. </p> - -<p> - An alternative approach to dynamic linking is to rebuild the Ruby interpreter - with your extension module added to it. In the past, this approach was - sometimes necessary due to limitations in dynamic loading support on certain - machines. However, the situation has improved greatly over the last few years - and you should not consider this approach unless there is really no other - option. - </p> - - -<p>The usual procedure for adding a new module to Ruby involves finding the Ruby - source, adding an entry to the <tt>ext/Setup</tt> file, adding your directory - to the list of extensions in the file, and finally rebuilding Ruby. - </p> - - <p><a name="n8"></a></p> -<h3><a name="Ruby_nn8"></a>30.1.6 Compilation of C++ extensions</h3> +<h3><a name="Ruby_nn8"></a>30.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> - On most machines, C++ extension modules should be linked using the C++ - compiler. For example: - </p> - - -<div class="code"> - +<div class="code shell"> <pre>$ <b>swig -c++ -ruby example.i</b><br>$ <b>g++ -c example.cxx</b><br>$ <b>g++ -c example_wrap.cxx -I/usr/local/lib/ruby/1.6/i686-linux</b><br>$ <b>g++ -shared example.o example_wrap.o -o example.so</b> </pre> - </div> +</div> - -<p> - If you've written an <tt>extconf.rb</tt> script to automatically generate a <tt>Makefile</tt> - for your C++ extension module, keep in mind that (as of this writing) Ruby - still uses <tt>gcc</tt> and not <tt>g++</tt> as its linker. As a result, the - required C++ runtime library support will not be automatically linked into your - extension module and it may fail to load on some platforms. A workaround for - this problem is use the <tt>mkmf</tt> module's <tt>append_library()</tt> method - to add one of the C++ runtime libraries to the list of libraries linked into - your extension, e.g. - </p> +<p> If you've written an <tt>extconf.rb</tt> script +to automatically generate a <tt>Makefile</tt> for your C++ +extension module, keep in mind that (as of this writing) Ruby still +uses <tt>gcc</tt> and not <tt>g++</tt> as its +linker. As a result, the required C++ runtime library support will not +be automatically linked into your extension module and it may fail to +load on some platforms. A workaround for this problem is use the <tt>mkmf</tt> +module's <tt>append_library()</tt> method to add one of +the C++ runtime libraries to the list of libraries linked into your +extension, e.g. </p> - -<div class="code"> - +<div class="code targetlang"> <pre>require 'mkmf'<br>$libs = append_library($libs, "supc++")<br>create_makefile('example')<br></pre> - </div> +</div> -<h2><a name="Ruby_nn9"></a>30.2 Building Ruby Extensions under Windows 95/NT</h2> +<h2><a name="Ruby_nn9"></a>30.2 Building Ruby +Extensions under Windows 95/NT</h2> +<p> Building a SWIG extension to Ruby under Windows 95/NT is +roughly similar to the process used with Unix. Normally, you will want +to produce a DLL that can be loaded into the Ruby interpreter. For all +recent versions of Ruby, the procedure described above (i.e. using an <tt>extconf.rb</tt> +script) will work with Windows as well; you should be able to build +your code into a DLL by typing: </p> - - -<p> - Building a SWIG extension to Ruby under Windows 95/NT is roughly similar to the - process used with Unix. Normally, you will want to produce a DLL that can be - loaded into the Ruby interpreter. For all recent versions of Ruby, the - procedure described above (i.e. using an <tt>extconf.rb</tt> script) will work - with Windows as well; you should be able to build your code into a DLL by - typing: - </p> - - -<div class="code"> - +<div class="code shell"> <pre>C:\swigtest> <b>ruby extconf.rb</b><br>C:\swigtest> <b>nmake</b><br>C:\swigtest> <b>nmake install</b> </pre> - </div> +</div> - -<p> - The remainder of this section covers the process of compiling SWIG-generated - Ruby extensions with Microsoft Visual C++ 6 (i.e. within the Developer Studio - IDE, instead of using the command line tools). In order to build extensions, - you may need to download the source distribution to the Ruby package, as you - will need the Ruby header files. - </p> +<p> The remainder of this section covers the process of compiling +SWIG-generated Ruby extensions with Microsoft Visual C++ 6 (i.e. within +the Developer Studio IDE, instead of using the command line tools). In +order to build extensions, you may need to download the source +distribution to the Ruby package, as you will need the Ruby header +files. </p> - <p><a name="n10"></a></p> -<h3><a name="Ruby_nn10"></a>30.2.1 Running SWIG from Developer Studio</h3> +<h3><a name="Ruby_nn10"></a>30.2.1 Running +SWIG from Developer Studio</h3> +<p> If you are developing your application within Microsoft +developer studio, SWIG can be invoked as a custom build option. The +process roughly follows these steps : </p> - - -<p> - If you are developing your application within Microsoft developer studio, SWIG - can be invoked as a custom build option. The process roughly follows these - steps : - </p> - - <ul> - <li> - Open up a new workspace and use the AppWizard to select a DLL project. - </li> + <li> Open up a new workspace and use the AppWizard to select a +DLL project. </li> - <li> - Add both the SWIG interface file (the .i file), any supporting C files, and the - name of the wrapper file that will be created by SWIG (i.e. <tt>example_wrap.c</tt>). - Note : If using C++, choose a different suffix for the wrapper file such as <tt>example_wrap.cxx</tt>. - Don't worry if the wrapper file doesn't exist yet--Developer Studio will keep a - reference to it around. - </li> + <li> Add both the SWIG interface file (the .i file), any +supporting C files, and the name of the wrapper file that will be +created by SWIG (i.e. <tt>example_wrap.c</tt>). Note : If +using C++, choose a different suffix for the wrapper file such as <tt>example_wrap.cxx</tt>. +Don't worry if the wrapper file doesn't exist yet--Developer Studio +will keep a reference to it around. </li> - <li> - Select the SWIG interface file and go to the settings menu. Under settings, - select the "Custom Build" option. - </li> + <li> Select the SWIG interface file and go to the settings +menu. Under settings, select the "Custom Build" option. </li> - <li> - Enter "SWIG" in the description field. - </li> + <li> Enter "SWIG" in the description field. </li> - <li> - Enter "<tt>swig -ruby -o $(ProjDir)\$(InputName)_wrap.c $(InputPath)</tt>" in - the "Build command(s) field". You may have to include the path to swig.exe. - </li> + <li> Enter "<tt>swig -ruby -o +$(ProjDir)\$(InputName)_wrap.c $(InputPath)</tt>" in the "Build +command(s) field". You may have to include the path to swig.exe. </li> - <li> - Enter "<tt>$(ProjDir)\$(InputName)_wrap.c</tt>" in the "Output files(s) field". - </li> + <li> Enter "<tt>$(ProjDir)\$(InputName)_wrap.c</tt>" +in the "Output files(s) field". </li> - <li> - Next, select the settings for the entire project and go to the C/C++ tab and - select the Preprocessor category. Add NT=1 to the Preprocessor definitions. - This must be set else you will get compilation errors. Also add IMPORT to the - preprocessor definitions, else you may get runtime errors. Also add the include - directories for your Ruby installation under "Additional include directories". - </li> + <li> Next, select the settings for the entire project and go to +the C/C++ tab and select the Preprocessor category. Add NT=1 to the +Preprocessor definitions. This must be set else you will get +compilation errors. Also add IMPORT to the preprocessor definitions, +else you may get runtime errors. Also add the include directories for +your Ruby installation under "Additional include directories". </li> - <li> - Next, select the settings for the entire project and go to the Link tab and - select the General category. Set the name of the output file to match the name - of your Ruby module (i.e.. example.dll). Next add the Ruby library file to your - link libraries under Object/Library modules. For example "mswin32-ruby16.lib. - You also need to add the path to the library under the Input tab - Additional - library path. - </li> + <li> Next, select the settings for the entire project and go to +the Link tab and select the General category. Set the name of the +output file to match the name of your Ruby module (i.e.. example.dll). +Next add the Ruby library file to your link libraries under +Object/Library modules. For example "mswin32-ruby16.lib. You also need +to add the path to the library under the Input tab - Additional library +path. </li> - <li> - Build your project. - </li> + <li> Build your project. </li> - </ul> - -<p> - Now, assuming all went well, SWIG will be automatically invoked when you build - your project. Any changes made to the interface file will result in SWIG being - automatically invoked to produce a new version of the wrapper file. To 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> Now, assuming all went well, SWIG will be automatically +invoked when you build your project. Any changes made to the interface +file will result in SWIG being automatically invoked to produce a new +version of the wrapper file. To 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> - -<div class="code"> - +<div class="code targetlang"> <pre># file: run.rb<br>require 'Example'<br><br># Call a c function<br>print "Foo = ", Example.Foo, "\n"<br></pre> - </div> +</div> - -<p> - Ensure the dll just built is in your path or current directory, then run the - Ruby script from the DOS/Command prompt: - </p> +<p> Ensure the dll just built is in your path or current +directory, then run the Ruby script from the DOS/Command prompt: </p> - -<div class="code"> - +<div class="code shell"> <pre>C:\swigtest> <b>ruby run.rb</b><br>Foo = 3.0<br></pre> - </div> +</div> -<h2><a name="Ruby_nn11"></a>30.3 The Ruby-to-C/C++ Mapping</h2> +<h2><a name="Ruby_nn11"></a>30.3 The +Ruby-to-C/C++ Mapping</h2> +<p> This section describes the basics of how SWIG maps C or C++ +declarations in your SWIG interface files to Ruby constructs. </p> - - -<p> - This section describes the basics of how SWIG maps C or C++ declarations in - your SWIG interface files to Ruby constructs. - </p> - <h3><a name="Ruby_nn12"></a>30.3.1 Modules</h3> +<p> The SWIG <tt>%module</tt> directive specifies +the name of the Ruby module. If you specify: </p> - - -<p> - The SWIG <tt>%module</tt> directive specifies the name of the Ruby module. If - you specify: - </p> - - <div class="code"> - <pre>%module example</pre> - </div> +</div> - -<p> - then everything is wrapped into a Ruby module named <tt>Example</tt> that is - nested directly under the global module. You can specify a more deeply nested - module by specifying the fully-qualified module name in quotes, e.g. - </p> +<p> then everything is wrapped into a Ruby module named <tt>Example</tt> +that is nested directly under the global module. You can specify a more +deeply nested module by specifying the fully-qualified module name in +quotes, e.g. </p> - <div class="code"> - <pre>%module "foo::bar::spam"</pre> - </div> +</div> - -<p> - An alternate method of specifying a nested module name is to use the - <span style="font-family: monospace;">-prefix</span> - option on the SWIG command line. The prefix that you specify with this option - will be prepended to the module name specified with the - <span style="font-family: monospace;">%module</span> - directive in your SWIG interface file. So for example, this declaration at the - top of your SWIG interface file:<br> +<p> An alternate method of specifying a nested module name is to +use the <span style="font-family: monospace;">-prefix</span> +option on the SWIG command line. The prefix that you specify with this +option will be prepended to the module name specified with the <span style="font-family: monospace;">%module</span> +directive in your SWIG interface file. So for example, this declaration +at the top of your SWIG interface file:<br> - </p> +</p> - <div class="code"> - <pre>%module "foo::bar::spam"</pre> - </div> +</div> - -<p> - will result in a nested module name of - <span style="font-family: monospace;">Foo::Bar::Spam</span>, but you can - achieve the - <span style="font-style: italic;">same</span> - effect by specifying:<br> +<p> will result in a nested module name of <span style="font-family: monospace;">Foo::Bar::Spam</span>, +but you can achieve the <span style="font-style: italic;">same</span> +effect by specifying:<br> - </p> +</p> - <div class="code"> - <pre>%module spam</pre> - </div> +</div> - -<p> - and then running SWIG with the - <span style="font-family: monospace;">-prefix</span> - command line option:<br> +<p> and then running SWIG with the <span style="font-family: monospace;">-prefix</span> command +line option:<br> - </p> +</p> - -<div class="code"> - +<div class="code shell"> <pre>$ <b>swig -ruby -prefix "foo::bar::" example.i</b></pre> - </div> +</div> - -<p> - Starting with SWIG 1.3.20, you can also choose to wrap everything into the - global module by specifying the <tt>-globalmodule</tt> option on the SWIG - command line, i.e. - </p> +<p> Starting with SWIG 1.3.20, you can also choose to wrap +everything into the global module by specifying the <tt>-globalmodule</tt> +option on the SWIG command line, i.e. </p> - -<div class="code"> - +<div class="code shell"> <pre>$ <b>swig -ruby -globalmodule example.i</b></pre> - </div> +</div> - -<p> - Note that this does not relieve you of the requirement of specifying the SWIG - module name with the <tt>%module</tt> directive (or the <tt>-module</tt> command-line - option) as described earlier. - </p> +<p> Note that this does not relieve you of the requirement of +specifying the SWIG module name with the <tt>%module</tt> +directive (or the <tt>-module</tt> command-line option) as +described earlier. </p> - -<p>When choosing a module name, do not use the same name as a built-in Ruby command - or standard module name, as the results may be unpredictable. Similarly, if - you're using the <tt>-globalmodule</tt> option to wrap everything into the - global module, take care that the names of your constants, classes and methods - don't conflict with any of Ruby's built-in names. - </p> +<p>When choosing a module name, do not use the same name as a +built-in Ruby command or standard module name, as the results may be +unpredictable. Similarly, if you're using the <tt>-globalmodule</tt> +option to wrap everything into the global module, take care that the +names of your constants, classes and methods don't conflict with any of +Ruby's built-in names. </p> <h3><a name="Ruby_nn13"></a>30.3.2 Functions</h3> +<p> Global functions are wrapped as Ruby module methods. For +example, given the SWIG interface file <tt>example.i</tt>: +</p> - - -<p> - Global functions are wrapped as Ruby module methods. For example, given the - SWIG interface file <tt>example.i</tt>: - </p> - - <div class="code"> - <pre>%module example<br><br>int fact(int n);<br></pre> - </div> +</div> - -<p> - and C source file <tt>example.c</tt>: - </p> +<p> and C source file <tt>example.c</tt>: </p> - <div class="code"> - <pre>int fact(int n) {<br> if (n == 0)<br> return 1;<br> return (n * fact(n-1));<br>}<br></pre> - </div> +</div> - -<p> - SWIG will generate a method <i>fact</i> in the <i>Example</i> module that can - be used like so: - </p> +<p> SWIG will generate a method <i>fact</i> in the <i>Example</i> +module that can be used like so: </p> - -<div class="code"> - +<div class="code targetlang"> <pre>$ <b>irb</b><br>irb(main):001:0> <b>require 'example'</b><br>true<br>irb(main):002:0> <b>Example.fact(4)</b><br>24<br></pre> - </div> +</div> -<h3><a name="Ruby_nn14"></a>30.3.3 Variable Linking</h3> +<h3><a name="Ruby_nn14"></a>30.3.3 Variable +Linking</h3> +<p> C/C++ global variables are wrapped as a pair of singleton +methods for the module: one to get the value of the global variable and +one to set it. For example, the following SWIG interface file declares +two global variables: </p> - - -<p> - C/C++ global variables are wrapped as a pair of singleton methods for the - module: one to get the value of the global variable and one to set it. For - example, the following SWIG interface file declares two global variables: - </p> - - <div class="code"> - <pre>// SWIG interface file with global variables<br>%module example<br>...<br>%inline %{<br>extern int variable1;<br>extern double Variable2;<br>%}<br>...<br></pre> - </div> +</div> - -<p> - Now look at the Ruby interface:</p> +<p> Now look at the Ruby interface:</p> - -<div class="code"> - +<div class="code targetlang"> <pre>$ <b>irb</b><br>irb(main):001:0> <b>require 'Example'</b><br>true<br>irb(main):002:0> <b>Example.variable1 = 2</b><br>2<br>irb(main):003:0> <b>Example.Variable2 = 4 * 10.3</b><br>41.2<br>irb(main):004:0> <b>Example.Variable2</b><br>41.2<br></pre> - </div> +</div> - -<p> - If you make an error in variable assignment, you will receive an error message. - For example: - </p> +<p> If you make an error in variable assignment, you will receive +an error message. For example: </p> - -<div class="code"> - +<div class="code targetlang"> <pre>irb(main):005:0> <b>Example.Variable2 = "hello"</b><br>TypeError: no implicit conversion to float from string<br>from (irb):5:in `Variable2='<br>from (irb):5<br></pre> - </div> +</div> - -<p> - If a variable is declared as <tt>const</tt>, it is wrapped as a read-only - variable. Attempts to modify its value will result in an error. - </p> +<p> If a variable is declared as <tt>const</tt>, it +is wrapped as a read-only variable. Attempts to modify its value will +result in an error. </p> - -<p>To make ordinary variables read-only, you can also use the <tt>%immutable</tt> directive. - For example: - </p> +<p>To make ordinary variables read-only, you can also use the <tt>%immutable</tt> +directive. For example: </p> - <div class="code"> - <pre>%immutable;<br>%inline %{<br>extern char *path;<br>%}<br>%mutable;<br></pre> - </div> +</div> - -<p> - The <tt>%immutable</tt> directive stays in effect until it is explicitly - disabled using <tt>%mutable</tt>. - </p> +<p> The <tt>%immutable</tt> directive stays in +effect until it is explicitly disabled using <tt>%mutable</tt>. +</p> <h3><a name="Ruby_nn15"></a>30.3.4 Constants</h3> +<p> C/C++ constants are wrapped as module constants initialized +to the appropriate value. To create a constant, use <tt>#define</tt> +or the <tt>%constant</tt> directive. For example: </p> - - -<p> - C/C++ constants are wrapped as module constants initialized to the appropriate - value. To create a constant, use <tt>#define</tt> or the <tt>%constant</tt> directive. - For example: - </p> - - <div class="code"> - <pre>#define PI 3.14159<br>#define VERSION "1.0"<br><br>%constant int FOO = 42;<br>%constant const char *path = "/usr/local";<br><br>const int BAR = 32;<br></pre> - </div> +</div> - -<p> - Remember to use the :: operator in Ruby to get at these constant values, e.g. - </p> +<p> Remember to use the :: operator in Ruby to get at these +constant values, e.g. </p> - -<div class="code"> - +<div class="code targetlang"> <pre>$ <b>irb</b><br>irb(main):001:0> <b>require 'Example'</b><br>true<br>irb(main):002:0> <b>Example::PI</b><br>3.14159<br></pre> - </div> +</div> <h3><a name="Ruby_nn16"></a>30.3.5 Pointers</h3> +<p> "Opaque" pointers to arbitrary C/C++ types (i.e. types that +aren't explicitly 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> - "Opaque" pointers to arbitrary C/C++ types (i.e. types that aren't explicitly - declared in your SWIG interface file) are wrapped as data objects. So, for - example, consider a SWIG interface file containing only the declarations: - </p> - - <div class="code"> - <pre>Foo *get_foo();<br>void set_foo(Foo *foo);<br></pre> - </div> +</div> - -<p> - For this case, the <i>get_foo()</i> method returns an instance of an internally - generated Ruby class: - </p> +<p> For this case, the <i>get_foo()</i> method +returns an instance of an internally generated Ruby class: </p> - -<div class="code"> - +<div class="code targetlang"> <pre>irb(main):001:0> <b>foo = Example::get_foo()</b><br>#<SWIG::TYPE_p_Foo:0x402b1654><br></pre> - </div> +</div> - -<p> - A <tt>NULL</tt> pointer is always represented by the Ruby <tt>nil</tt> object. - </p> +<p> A <tt>NULL</tt> pointer is always represented by +the Ruby <tt>nil</tt> object. </p> <h3><a name="Ruby_nn17"></a>30.3.6 Structures</h3> +<p> 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> - 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> - - <div class="code"> - <pre>struct Vector {<br> double x, y;<br>};<br></pre> - </div> +</div> - -<p> - 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> 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> - -<div class="code"> - +<div class="code targetlang"> <pre>$ <b>irb</b><br>irb(main):001:0> <b>require 'Example'</b><br>true<br>irb(main):002:0> <b>f = Example::Vector.new</b><br>#<Example::Vector:0x4020b268><br>irb(main):003:0> <b>f.x = 10</b><br>nil<br>irb(main):004:0> <b>f.x</b><br>10.0<br></pre> - </div> +</div> - -<p> - Similar access is provided for unions and the public data members of C++ - classes.</p> +<p> Similar access is provided for unions and the public data +members of C++ classes.</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 C++, <tt>private</tt> - may also be used). For example: - </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 C++, <tt>private</tt> may also be used). For +example: </p> - <div class="code"> - <pre>struct Foo {<br> ...<br> %immutable;<br> int x; /* Read-only members */<br> char *name;<br> %mutable;<br> ...<br>};<br></pre> - </div> +</div> - -<p> - When <tt>char *</tt> members of a structure are wrapped, the contents are - assumed to be dynamically allocated using <tt>malloc</tt> or <tt>new</tt> (depending - on whether or not SWIG is run with the <tt>-c++</tt> option). When the - structure member is set, the old contents will be released and a new value - created. If this is not the behavior you want, you will have to use a typemap - (described shortly). - </p> +<p> When <tt>char *</tt> members of a structure are +wrapped, the contents are assumed to be dynamically allocated using <tt>malloc</tt> +or <tt>new</tt> (depending on whether or not SWIG is run +with the <tt>-c++</tt> option). When the structure member +is set, the old contents will be released and a new value created. If +this is not the behavior you want, you will have to use a typemap +(described shortly). </p> - -<p>Array members are normally wrapped as read-only. For example, this code: - </p> +<p>Array members are normally wrapped as read-only. For example, +this code: </p> - <div class="code"> - <pre>struct Foo {<br> int x[50];<br>};<br></pre> - </div> +</div> - -<p> - produces a single accessor function like this: - </p> +<p> produces a single accessor function like this: </p> - <div class="code"> - <pre>int *Foo_x_get(Foo *self) {<br> return self->x;<br>};<br></pre> - </div> +</div> - -<p> - If you want to set an array member, you will need to supply a "memberin" - 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). - </p> +<p> If you want to set an array member, you will need to supply a +"memberin" 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). </p> - -<p>When structure members are wrapped, they are handled as pointers. For example, - </p> +<p>When structure members are wrapped, they are handled as +pointers. For example, </p> - <div class="code"> - <pre>struct Foo {<br> ...<br>};<br><br>struct Bar {<br> Foo f;<br>};<br></pre> - </div> +</div> - -<p> - generates accessor functions such as this: - </p> +<p> generates accessor functions such as this: </p> - <div class="code"> - <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> - </div> +</div> <h3><a name="Ruby_nn18"></a>30.3.7 C++ classes</h3> +<p> Like structs, C++ classes are wrapped by creating a new Ruby +class of the same name with accessor methods for the public class +member data. Additionally, public member functions for the class are +wrapped as Ruby instance methods, and public static member functions +are wrapped as Ruby singleton methods. So, given the C++ class +declaration: </p> - - -<p> - Like structs, C++ classes are wrapped by creating a new Ruby class of the same - name with accessor methods for the public class member data. Additionally, - public member functions for the class are wrapped as Ruby instance methods, and - public static member functions are wrapped as Ruby singleton methods. So, given - the C++ class declaration: - </p> - - <div class="code"> - <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> - </div> +</div> - -<p> - SWIG would create a <tt>List</tt> class with: - </p> +<p> SWIG would create a <tt>List</tt> class with: </p> - <ul> - <li> - instance methods <i>search</i>, <i>insert</i>, <i>remove</i>, and <i>get</i>; - </li> + <li> instance methods <i>search</i>, <i>insert</i>, + <i>remove</i>, and <i>get</i>; </li> - <li> - instance methods <i>length</i> and <i>length=</i> (to get and set the value of - the <i>length</i> data member); and, - </li> + <li> instance methods <i>length</i> and <i>length=</i> +(to get and set the value of the <i>length</i> data +member); and, </li> - <li> - a <i>print</i> singleton method for the class. - </li> + <li> a <i>print</i> singleton method for the +class. </li> - </ul> - -<p> - In Ruby, these functions are used as follows: - </p> +<p> In Ruby, these functions are used as follows: </p> - -<div class="code"> - +<div class="code targetlang"> <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> - </div> +</div> -<h3><a name="Ruby_nn19"></a>30.3.8 C++ Inheritance</h3> +<h3><a name="Ruby_nn19"></a>30.3.8 C++ +Inheritance</h3> +<p> The SWIG type-checker is fully aware of C++ inheritance. +Therefore, if you have classes like this: </p> - - -<p> - The SWIG type-checker is fully aware of C++ inheritance. Therefore, if you have - classes like this: - </p> - - <div class="code"> - <pre>class Parent {<br> ...<br>};<br><br>class Child : public Parent {<br> ...<br>};<br></pre> - </div> +</div> - -<p> - those classes are wrapped into a hierarchy of Ruby classes that reflect the - same inheritance structure. All of the usual Ruby utility methods work - normally: - </p> +<p> those classes are wrapped into a hierarchy of Ruby classes +that reflect the same inheritance structure. All of the usual Ruby +utility methods work normally: </p> - <div class="code"> - <pre>irb(main):001:0> <b>c = Child.new</b><br>#<Bar:0x4016efd4><br>irb(main):002:0> <b>c.instance_of? Child</b><br>true<br>irb(main):003:0> <b>b.instance_of? Parent</b><br>false<br>irb(main):004:0> <b>b.is_a? Child</b><br>true<br>irb(main):005:0> <b>b.is_a? Parent</b><br>true<br>irb(main):006:0> <b>Child < Parent</b><br>true<br>irb(main):007:0> <b>Child > Parent</b><br>false<br></pre> - </div> +</div> - -<p> - Furthermore, if you have a function like this: - </p> +<p> Furthermore, if you have a function like this: </p> - <div class="code"> - <pre>void spam(Parent *f);<br></pre> - </div> +</div> - -<p> - then the function <tt>spam()</tt> accepts <tt>Parent</tt>* or a pointer to any - class derived from <tt>Parent</tt>. - </p> +<p> then the function <tt>spam()</tt> accepts <tt>Parent</tt>* +or a pointer to any class derived from <tt>Parent</tt>. </p> - -<p>Until recently, the Ruby module for SWIG didn't support multiple inheritance, - and this is still the default behavior. This doesn't mean that you can't wrap - C++ classes which inherit from multiple base classes; it simply means that only - the <b>first</b> base class listed in the class declaration is considered, and - any additional base classes are ignored. As an example, consider a SWIG - interface file with a declaration like this: - </p> +<p>Until recently, the Ruby module for SWIG didn't support +multiple inheritance, and this is still the default behavior. This +doesn't mean that you can't wrap C++ classes which inherit from +multiple base classes; it simply means that only the <b>first</b> +base class listed in the class declaration is considered, and any +additional base classes are ignored. As an example, consider a SWIG +interface file with a declaration like this: </p> - <div class="code"> - <pre>class Derived : public Base1, public Base2<br>{<br> ...<br>};<br></pre> - </div> +</div> - -<p> - For this case, the resulting Ruby class (<tt>Derived</tt>) will only consider <tt>Base1</tt> - as its superclass. It won't inherit any of <tt>Base2</tt>'s member functions or - data and it won't recognize <tt>Base2</tt> as an "ancestor" of <tt>Derived</tt> - (i.e. the <em>is_a?</em> relationship would fail). When SWIG processes this - interface file, you'll see a warning message like: - </p> +<p> For this case, the resulting Ruby class (<tt>Derived</tt>) +will only consider <tt>Base1</tt> as its superclass. It +won't inherit any of <tt>Base2</tt>'s member functions or +data and it won't recognize <tt>Base2</tt> as an +"ancestor" of <tt>Derived</tt> (i.e. the <em>is_a?</em> +relationship would fail). When SWIG processes this interface file, +you'll see a warning message like: </p> - -<div class="code"> - +<div class="code shell"> <pre>example.i:5: Warning(802): Warning for Derived: Base Base2 ignored.<br>Multiple inheritance is not supported in Ruby.<br></pre> - </div> +</div> - -<p> - Starting with SWIG 1.3.20, the Ruby module for SWIG provides limited support - for multiple inheritance. Because the approach for dealing with multiple - inheritance introduces some limitations, this is an optional feature that you - can activate with the <tt>-minherit</tt> command-line option: - </p> +<p> Starting with SWIG 1.3.20, the Ruby module for SWIG provides +limited support for multiple inheritance. Because the approach for +dealing with multiple inheritance introduces some limitations, this is +an optional feature that you can activate with the <tt>-minherit</tt> +command-line option: </p> - -<div class="code"> - +<div class="code shell"> <pre>$ <b>swig -c++ -ruby -minherit example.i</b></pre> - </div> +</div> - -<p> - Using our previous example, if your SWIG interface file contains a declaration - like this: - </p> +<p> Using our previous example, if your SWIG interface file +contains a declaration like this: </p> - <div class="code"> - <pre>class Derived : public Base1, public Base2<br>{<br> ...<br>};<br></pre> - </div> +</div> - -<p> - and you run SWIG with the <tt>-minherit</tt> command-line option, then you will - end up with a Ruby class <tt>Derived</tt> that appears to "inherit" the member - data and functions from both <tt>Base1</tt> and <tt>Base2</tt>. What actually - happens is that three different top-level classes are created, with Ruby's <tt>Object</tt> - class as their superclass. Each of these classes defines a nested module named <tt>Impl</tt>, - and it's in these nested <tt>Impl</tt> modules that the actual instance methods - for the classes are defined, i.e. - </p> +<p> and you run SWIG with the <tt>-minherit</tt> +command-line option, then you will end up with a Ruby class <tt>Derived</tt> +that appears to "inherit" the member data and functions from both <tt>Base1</tt> +and <tt>Base2</tt>. What actually happens is that three +different top-level classes are created, with Ruby's <tt>Object</tt> +class as their superclass. Each of these classes defines a nested +module named <tt>Impl</tt>, and it's in these nested <tt>Impl</tt> +modules that the actual instance methods for the classes are defined, +i.e. </p> - -<div class="code"> - +<div class="code targetlang"> <pre>class Base1<br> module Impl<br> # Define Base1 methods here<br> end<br> include Impl<br>end<br><br>class Base2<br> module Impl<br> # Define Base2 methods here<br> end<br> include Impl<br>end<br><br>class Derived<br> module Impl<br> include Base1::Impl<br> include Base2::Impl<br> # Define Derived methods here<br> end<br> include Impl<br>end<br></pre> - </div> +</div> - -<p> - Observe that after the nested <tt>Impl</tt> module for a class is defined, it - is mixed-in to the class itself. Also observe that the <tt>Derived::Impl</tt> module - first mixes-in its base classes' <tt>Impl</tt> modules, thus "inheriting" all - of their behavior. - </p> +<p> Observe that after the nested <tt>Impl</tt> +module for a class is defined, it is mixed-in to the class itself. Also +observe that the <tt>Derived::Impl</tt> module first +mixes-in its base classes' <tt>Impl</tt> modules, thus +"inheriting" all of their behavior. </p> - -<p>The primary drawback is that, unlike the default mode of operation, neither <tt>Base1</tt> - nor <tt>Base2</tt> is a true superclass of <tt>Derived</tt> anymore: - </p> +<p>The primary drawback is that, unlike the default mode of +operation, neither <tt>Base1</tt> nor <tt>Base2</tt> +is a true superclass of <tt>Derived</tt> anymore: </p> - -<div class="code"> - +<div class="code targetlang"> <pre>obj = Derived.new<br>obj.is_a? Base1 # this will return false...<br>obj.is_a? Base2 # ... and so will this<br></pre> - </div> +</div> - -<p> - In most cases, this is not a serious problem since objects of type <tt>Derived</tt> - 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>). - </p> +<p> In most cases, this is not a serious problem since objects of +type <tt>Derived</tt> 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>). </p> -<h3><a name="Ruby_nn20"></a>30.3.9 C++ Overloaded Functions</h3> +<h3><a name="Ruby_nn20"></a>30.3.9 C++ +Overloaded Functions</h3> +<p> C++ overloaded functions, methods, and constructors are +mostly supported by SWIG. For example, if you have two functions like +this: </p> - - -<p> - C++ overloaded functions, methods, and constructors are mostly supported by - SWIG. For example, if you have two functions like this: - </p> - - <div class="code"> - <pre>void foo(int);<br>void foo(char *c);<br></pre> - </div> +</div> - -<p> - You can use them in Ruby in a straightforward manner: - </p> +<p> You can use them in Ruby in a straightforward manner: </p> - -<div class="code"> - +<div class="code targetlang"> <pre>irb(main):001:0> <b>foo(3)</b> # foo(int)<br>irb(main):002:0> <b>foo("Hello")</b> # foo(char *c)<br></pre> - </div> +</div> - <p>Similarly, if you have a class like this,</p> - <div class="code"> - <pre>class Foo {<br>public:<br> Foo();<br> Foo(const Foo &);<br> ...<br>};<br></pre> - </div> +</div> - <p>you can write Ruby code like this:</p> - -<div class="code"> - +<div class="code targetlang"> <pre>irb(main):001:0> <b>f = Foo.new</b> # Create a Foo<br>irb(main):002:0> <b>g = Foo.new(f)</b> # Copy f<br></pre> - </div> +</div> - -<p> - Overloading support is not quite as flexible as in C++. Sometimes there are - methods that SWIG can't disambiguate. For example: - </p> +<p> Overloading support is not quite as flexible as in C++. +Sometimes there are methods that SWIG can't disambiguate. For example: </p> - <div class="code"> - <pre>void spam(int);<br>void spam(short);<br></pre> - </div> +</div> - <p>or</p> - <div class="code"> - <pre>void foo(Bar *b);<br>void foo(Bar &b);<br></pre> - </div> +</div> - -<p> - If declarations such as these appear, you will get a warning message like this: - </p> +<p> If declarations such as these appear, you will get a warning +message like this: </p> - -<div class="code"> - +<div class="code shell"> <pre>example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int)<br>at example.i:11.<br> </pre> - </div> +</div> - -<p> - To fix this, you either need to ignore or rename one of the methods. For - example: - </p> +<p> To fix this, you either need to ignore or rename one of the +methods. For example: </p> - <div class="code"> - <pre>%rename(spam_short) spam(short);<br>...<br>void spam(int); <br>void spam(short); // Accessed as spam_short<br></pre> - </div> +</div> - <p>or</p> - <div class="code"> - <pre>%ignore spam(short);<br>...<br>void spam(int); <br>void spam(short); // Ignored<br></pre> - </div> +</div> - -<p> - SWIG resolves overloaded functions and methods using a disambiguation scheme - that ranks and sorts declarations according to a set of type-precedence rules. - The order in which declarations appear in the input does not matter except in - situations where ambiguity arises--in this case, the first declaration takes - precedence. - </p> +<p> SWIG resolves overloaded functions and methods using a +disambiguation scheme that ranks and sorts declarations according to a +set of type-precedence rules. The order in which declarations appear in +the input does not matter except in situations where ambiguity +arises--in this case, the first declaration takes precedence. </p> - -<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> +<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> -<h3><a name="Ruby_nn21"></a>30.3.10 C++ Operators</h3> +<h3><a name="Ruby_nn21"></a>30.3.10 C++ +Operators</h3> +<p> For the most part, overloaded operators are handled +automatically by SWIG and do not require any special treatment on your +part. So if your class declares an overloaded addition operator, e.g. </p> - - -<p> - For the most part, overloaded operators are handled automatically by SWIG and - do not require any special treatment on your part. So if your class declares an - overloaded addition operator, e.g. - </p> - - <div class="code"> - <pre>class Complex {<br> ...<br> Complex operator+(Complex &);<br> ...<br>};<br></pre> - </div> +</div> - -<p> - the resulting Ruby class will also support the addition (+) method correctly. - </p> +<p> the resulting Ruby class will also support the addition (+) +method correctly. </p> - -<p>For cases where SWIG's built-in support is not sufficient, C++ operators can be - wrapped using the <tt>%rename</tt> directive (available on SWIG 1.3.10 and - later releases). All you need to do is give the operator the name of a valid - Ruby identifier. For example: - </p> +<p>For cases where SWIG's built-in support is not sufficient, C++ +operators can be wrapped using the <tt>%rename</tt> +directive (availa... [truncated message content] |