/Doc/Manual/SWIGPlus.html
HTML | 4913 lines | 4131 code | 774 blank | 8 comment | 0 complexity | b56b941aec17b1b86722593c3e68a2ea MD5 | raw file
Possible License(s): 0BSD, GPL-2.0, LGPL-2.1
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <title>SWIG and C++</title>
- <link rel="stylesheet" type="text/css" href="style.css">
- </head>
- <body bgcolor="#ffffff">
- <H1><a name="SWIGPlus"></a>6 SWIG and C++</H1>
- <!-- INDEX -->
- <div class="sectiontoc">
- <ul>
- <li><a href="#SWIGPlus_nn2">Comments on C++ Wrapping</a>
- <li><a href="#SWIGPlus_nn3">Approach</a>
- <li><a href="#SWIGPlus_nn4">Supported C++ features</a>
- <li><a href="#SWIGPlus_nn5">Command line options and compilation</a>
- <li><a href="#SWIGPlus_nn38">Proxy classes</a>
- <ul>
- <li><a href="#SWIGPlus_nn39">Construction of proxy classes</a>
- <li><a href="#SWIGPlus_nn40">Resource management in proxies</a>
- <li><a href="#SWIGPlus_nn41">Language specific details</a>
- </ul>
- <li><a href="#SWIGPlus_nn6">Simple C++ wrapping</a>
- <ul>
- <li><a href="#SWIGPlus_nn7">Constructors and destructors</a>
- <li><a href="#SWIGPlus_nn8">Default constructors, copy constructors and implicit destructors</a>
- <li><a href="#SWIGPlus_nn9">When constructor wrappers aren't created</a>
- <li><a href="#SWIGPlus_nn10">Copy constructors</a>
- <li><a href="#SWIGPlus_nn11">Member functions</a>
- <li><a href="#SWIGPlus_nn12">Static members</a>
- <li><a href="#SWIGPlus_member_data">Member data</a>
- </ul>
- <li><a href="#SWIGPlus_default_args">Default arguments</a>
- <li><a href="#SWIGPlus_nn15">Protection</a>
- <li><a href="#SWIGPlus_nn16">Enums and constants</a>
- <li><a href="#SWIGPlus_nn17">Friends</a>
- <li><a href="#SWIGPlus_nn18">References and pointers</a>
- <li><a href="#SWIGPlus_nn19">Pass and return by value</a>
- <li><a href="#SWIGPlus_nn20">Inheritance</a>
- <li><a href="#SWIGPlus_nn21">A brief discussion of multiple inheritance, pointers, and type checking</a>
- <li><a href="#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods</a>
- <ul>
- <li><a href="#SWIGPlus_nn24">Dispatch function generation</a>
- <li><a href="#SWIGPlus_nn25">Ambiguity in Overloading</a>
- <li><a href="#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
- <li><a href="#SWIGPlus_nn27">Comments on overloading</a>
- </ul>
- <li><a href="#SWIGPlus_nn28">Wrapping overloaded operators</a>
- <li><a href="#SWIGPlus_class_extension">Class extension</a>
- <li><a href="#SWIGPlus_nn30">Templates</a>
- <li><a href="#SWIGPlus_nn31">Namespaces</a>
- <li><a href="#SWIGPlus_renaming_templated_types_namespaces">Renaming templated types in namespaces</a>
- <li><a href="#SWIGPlus_exception_specifications">Exception specifications</a>
- <li><a href="#SWIGPlus_catches">Exception handling with %catches</a>
- <li><a href="#SWIGPlus_nn33">Pointers to Members</a>
- <li><a href="#SWIGPlus_nn34">Smart pointers and operator->()</a>
- <li><a href="#SWIGPlus_nn35">Using declarations and inheritance</a>
- <li><a href="#SWIGPlus_nested_classes">Nested classes</a>
- <li><a href="#SWIGPlus_nn37">A brief rant about const-correctness</a>
- <li><a href="#SWIGPlus_nn42">Where to go for more information</a>
- </ul>
- </div>
- <!-- INDEX -->
- <p>
- This chapter describes SWIG's support for wrapping C++. As a prerequisite,
- you should first read the chapter <a href="SWIG.html#SWIG">SWIG Basics</a> to see
- how SWIG wraps ANSI C. Support for C++ builds upon ANSI C
- wrapping and that material will be useful in understanding this chapter.
- </p>
- <H2><a name="SWIGPlus_nn2"></a>6.1 Comments on C++ Wrapping</H2>
- <p>
- Because of its complexity and the fact that C++ can be
- difficult to integrate with itself let alone other languages, SWIG
- only provides support for a subset of C++ features. Fortunately,
- this is now a rather large subset.
- </p>
- <p>
- In part, the problem with C++ wrapping is that there is no
- semantically obvious (or automatic ) way to map many of its advanced
- features into other languages. As a simple example, consider the
- problem of wrapping C++ multiple inheritance to a target language with
- no such support. Similarly, the use of overloaded operators and
- overloaded functions can be problematic when no such capability exists
- in a target language.
- </p>
- <p>
- A more subtle issue with C++ has to do with the way that some C++
- programmers think about programming libraries. In the world of SWIG,
- you are really trying to create binary-level software components for
- use in other languages. In order for this to work, a "component" has
- to contain real executable instructions and there has to be some kind
- of binary linking mechanism for accessing its functionality. In
- contrast, C++ has increasingly relied upon generic programming and
- templates for much of its functionality.
- Although templates are a powerful feature, they are largely orthogonal
- to the whole notion of binary components and libraries. For example,
- an STL <tt>vector</tt> does not define any kind of binary object for
- which SWIG can just create a wrapper. To further complicate matters,
- these libraries often utilize a lot of behind the scenes magic in
- which the semantics of seemingly basic operations (e.g., pointer
- dereferencing, procedure call, etc.) can be changed in dramatic and
- sometimes non-obvious ways. Although this "magic" may present few
- problems in a C++-only universe, it greatly complicates the problem of
- crossing language boundaries and provides many opportunities to shoot
- yourself in the foot. You will just have to be careful.
- </p>
- <H2><a name="SWIGPlus_nn3"></a>6.2 Approach</H2>
- <p>
- To wrap C++, SWIG uses a layered approach to code generation.
- At the lowest level, SWIG generates a collection of procedural ANSI-C style
- wrappers. These wrappers take care of basic type conversion,
- type checking, error handling, and other low-level details of the C++ binding.
- These wrappers are also sufficient to bind C++ into any target language
- that supports built-in procedures. In some sense, you might view this
- layer of wrapping as providing a C library interface to C++.
- On top of the low-level procedural (flattened) interface, SWIG generates proxy classes
- that provide a natural object-oriented (OO) interface to the underlying code. The proxy classes are typically
- written in the target language itself. For instance, in Python, a real
- Python class is used to provide a wrapper around the underlying C++ object.
- </p>
- <p>
- It is important to emphasize that SWIG takes a deliberately
- conservative and non-intrusive approach to C++ wrapping. SWIG does not
- encapsulate C++ classes inside a special C++ adaptor, it does not rely
- upon templates, nor does it add in additional C++ inheritance when
- generating wrappers. The last thing that most C++ programs need is
- even more compiler magic. Therefore, SWIG tries to maintain a very
- strict and clean separation between the implementation of your C++
- application and the resulting wrapper code. You might say that SWIG
- has been written to follow the principle of least surprise--it does
- not play sneaky tricks with the C++ type system, it doesn't mess with
- your class hierarchies, and it doesn't introduce new semantics.
- Although this approach might not provide the most seamless integration
- with C++, it is safe, simple, portable, and debuggable.
- </p>
- <p>
- Some of this chapter focuses on the low-level procedural interface to
- C++ that is used as the foundation for all language modules. Keep in
- mind that the target languages also provide the high-level OO interface via
- proxy classes. More detailed coverage can be found in the documentation
- for each target language.
- </p>
- <H2><a name="SWIGPlus_nn4"></a>6.3 Supported C++ features</H2>
- <p>
- SWIG currently supports most C++ features including the following:</p>
- <ul>
- <li>Classes
- <li>Constructors and destructors
- <li>Virtual functions
- <li>Public inheritance (including multiple inheritance)
- <li>Static functions
- <li>Function and method overloading
- <li>Operator overloading for many standard operators
- <li>References
- <li>Templates (including specialization and member templates)
- <li>Pointers to members
- <li>Namespaces
- <li>Default parameters
- <li>Smart pointers
- </ul>
- <p>
- The following C++ features are not currently supported:</p>
- <ul>
- <li>Overloaded versions of certain operators (new, delete, etc.)
- <li>Nested classes, see <a href="#SWIGPlus_nested_classes">Nested classes</a> for workarounds.
- </ul>
- <p>
- As a rule of thumb, SWIG should not be used on raw C++ source files, use header files only.
- </p>
- <p>
- SWIG's C++ support is an ongoing project so some of these limitations may be lifted
- in future releases. However, we make no promises. Also, submitting a bug report is a very
- good way to get problems fixed (wink).
- </p>
- <H2><a name="SWIGPlus_nn5"></a>6.4 Command line options and compilation</H2>
- <p>
- When wrapping C++ code, it is critical that SWIG be called with the
- `<tt>-c++</tt>' option. This changes the way a number of critical
- features such as memory management are handled. It
- also enables the recognition of C++ keywords. Without the <tt>-c++</tt>
- flag, SWIG will either issue a warning or a large number of syntax
- errors if it encounters C++ code in an interface file.</p>
- <p>
- When compiling and linking the resulting wrapper file, it is normal
- to use the C++ compiler. For example:
- </p>
- <div class="shell">
- <pre>
- $ swig -c++ -tcl example.i
- $ c++ -c example_wrap.cxx
- $ c++ example_wrap.o $(OBJS) -o example.so
- </pre>
- </div>
- <p>
- Unfortunately, the process varies slightly on each platform. Make sure
- you refer to the documentation on each target language for further
- details. The SWIG Wiki also has further details.
- </p>
- <b>Compatibility Note:</b> Early versions of SWIG generated just a flattened low-level C style API to C++ classes by default.
- The <tt>-noproxy</tt> commandline option is recognised by many target languages and will generate just this
- interface as in earlier versions.
- <H2><a name="SWIGPlus_nn38"></a>6.5 Proxy classes</H2>
- <p>
- In order to provide a natural mapping from C++ classes to the target language classes, SWIG's target
- languages mostly wrap C++ classes with special proxy classes. These
- proxy classes are typically implemented in the target language itself.
- For example, if you're building a Python module, each C++ class is
- wrapped by a Python proxy class. Or if you're building a Java module, each
- C++ class is wrapped by a Java proxy class.
- </p>
- <H3><a name="SWIGPlus_nn39"></a>6.5.1 Construction of proxy classes</H3>
- <p>
- Proxy classes are always constructed as an extra layer of wrapping that uses low-level
- accessor functions. To illustrate, suppose you had a
- C++ class like this:
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- Foo();
- ~Foo();
- int bar(int x);
- int x;
- };
- </pre>
- </div>
- <p>
- Using C++ as pseudocode, a proxy class looks something like this:
- </p>
- <div class="code">
- <pre>
- class FooProxy {
- private:
- Foo *self;
- public:
- FooProxy() {
- self = new_Foo();
- }
- ~FooProxy() {
- delete_Foo(self);
- }
- int bar(int x) {
- return Foo_bar(self,x);
- }
- int x_get() {
- return Foo_x_get(self);
- }
- void x_set(int x) {
- Foo_x_set(self,x);
- }
- };
- </pre>
- </div>
- <p>
- Of course, always keep in mind that the real proxy class is written in the target language.
- For example, in Python, the proxy might look roughly like this:
- </p>
- <div class="targetlang">
- <pre>
- class Foo:
- def __init__(self):
- self.this = new_Foo()
- def __del__(self):
- delete_Foo(self.this)
- def bar(self,x):
- return Foo_bar(self.this,x)
- def __getattr__(self,name):
- if name == 'x':
- return Foo_x_get(self.this)
- ...
- def __setattr__(self,name,value):
- if name == 'x':
- Foo_x_set(self.this,value)
- ...
- </pre>
- </div>
- <p>
- Again, it's important to emphasize that the low-level accessor functions are always used by the
- proxy classes.
- Whenever possible, proxies try to take advantage of language features that are similar to C++. This
- might include operator overloading, exception handling, and other features.
- </p>
- <H3><a name="SWIGPlus_nn40"></a>6.5.2 Resource management in proxies</H3>
- <p>
- A major issue with proxies concerns the memory management of wrapped objects. Consider the following
- C++ code:
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- Foo();
- ~Foo();
- int bar(int x);
- int x;
- };
- class Spam {
- public:
- Foo *value;
- ...
- };
- </pre>
- </div>
- <p>
- Consider some script code that uses these classes:
- </p>
- <div class="targetlang">
- <pre>
- f = Foo() # Creates a new Foo
- s = Spam() # Creates a new Spam
- s.value = f # Stores a reference to f inside s
- g = s.value # Returns stored reference
- g = 4 # Reassign g to some other value
- del f # Destroy f
- </pre>
- </div>
- <p>
- Now, ponder the resulting memory management issues. When objects are
- created in the script, the objects are wrapped by newly created proxy
- classes. That is, there is both a new proxy class instance and a new
- instance of the underlying C++ class. In this example, both
- <tt>f</tt> and <tt>s</tt> are created in this way. However, the
- statement <tt>s.value</tt> is rather curious---when executed, a
- pointer to <tt>f</tt> is stored inside another object. This means
- that the scripting proxy class <em>AND</em> another C++ class share a
- reference to the same object. To make matters even more interesting,
- consider the statement <tt>g = s.value</tt>. When executed, this
- creates a new proxy class <tt>g</tt> that provides a wrapper around the
- C++ object stored in <tt>s.value</tt>. In general, there is no way to
- know where this object came from---it could have been created by the
- script, but it could also have been generated internally. In this
- particular example, the assignment of <tt>g</tt> results in a second
- proxy class for <tt>f</tt>. In other words, a reference to <tt>f</tt>
- is now shared by two proxy classes <em>and</em> a C++ class.
- </p>
- <p>
- Finally, consider what happens when objects are destroyed. In the
- statement, <tt>g=4</tt>, the variable <tt>g</tt> is reassigned. In
- many languages, this makes the old value of <tt>g</tt> available for
- garbage collection. Therefore, this causes one of the proxy classes
- to be destroyed. Later on, the statement <tt>del f</tt> destroys the
- other proxy class. Of course, there is still a reference to the
- original object stored inside another C++ object. What happens to it?
- Is the object still valid?
- </p>
- <p>
- To deal with memory management problems, proxy classes provide an API
- for controlling ownership. In C++ pseudocode, ownership control might look
- roughly like this:
- </p>
- <div class="code">
- <pre>
- class FooProxy {
- public:
- Foo *self;
- int thisown;
- FooProxy() {
- self = new_Foo();
- thisown = 1; // Newly created object
- }
- ~FooProxy() {
- if (thisown) delete_Foo(self);
- }
- ...
- // Ownership control API
- void disown() {
- thisown = 0;
- }
- void acquire() {
- thisown = 1;
- }
- };
- class FooPtrProxy: public FooProxy {
- public:
- FooPtrProxy(Foo *s) {
- self = s;
- thisown = 0;
- }
- };
- class SpamProxy {
- ...
- FooProxy *value_get() {
- return FooPtrProxy(Spam_value_get(self));
- }
- void value_set(FooProxy *v) {
- Spam_value_set(self,v->self);
- v->disown();
- }
- ...
- };
- </pre>
- </div>
- <p>
- Looking at this code, there are a few central features:
- </p>
- <ul>
- <li>Each proxy class keeps an extra flag to indicate ownership. C++ objects are only destroyed
- if the ownership flag is set.
- </li>
- <li>When new objects are created in the target language, the ownership flag is set.
- </li>
- <li>When a reference to an internal C++ object is returned, it is wrapped by a proxy
- class, but the proxy class does not have ownership.
- </li>
- <li>In certain cases, ownership is adjusted. For instance, when a value is assigned to the member of
- a class, ownership is lost.
- </li>
- <li>Manual ownership control is provided by special <tt>disown()</tt> and <tt>acquire()</tt> methods.
- </li>
- </ul>
- <p>
- Given the tricky nature of C++ memory management, it is impossible for proxy classes to automatically handle
- every possible memory management problem. However, proxies do provide a mechanism for manual control that
- can be used (if necessary) to address some of the more tricky memory management problems.
- </p>
- <H3><a name="SWIGPlus_nn41"></a>6.5.3 Language specific details</H3>
- <p>
- Language specific details on proxy classes are contained in the chapters describing each target language. This
- chapter has merely introduced the topic in a very general way.
- </p>
- <H2><a name="SWIGPlus_nn6"></a>6.6 Simple C++ wrapping</H2>
- <p>
- The following code shows a SWIG interface file for a simple C++
- class.</p>
- <div class="code"><pre>
- %module list
- %{
- #include "list.h"
- %}
- // Very simple C++ example for linked list
- class List {
- public:
- List();
- ~List();
- int search(char *value);
- void insert(char *);
- void remove(char *);
- char *get(int n);
- int length;
- static void print(List *l);
- };
- </pre></div>
- <p>
- To generate wrappers for this class, SWIG first reduces the class to a collection of low-level C-style
- accessor functions which are then used by the proxy classes.
- </p>
- <H3><a name="SWIGPlus_nn7"></a>6.6.1 Constructors and destructors</H3>
- <p>
- C++ constructors and destructors are translated into accessor
- functions such as the following :</p>
- <div class="code"><pre>
- List * new_List(void) {
- return new List;
- }
- void delete_List(List *l) {
- delete l;
- }
- </pre></div>
- <H3><a name="SWIGPlus_nn8"></a>6.6.2 Default constructors, copy constructors and implicit destructors</H3>
- <p>
- Following the C++ rules for implicit constructor and destructors, SWIG
- will automatically assume there is one even when they are not
- explicitly declared in the class interface.
- </p>
- <p>
- In general then:
- </p>
- <ul>
- <li>
- If a C++ class does not declare any explicit constructor, SWIG will
- automatically generate a wrapper for one.
- </li>
- <li>
- If a C++ class does not declare an explicit copy constructor, SWIG will
- automatically generate a wrapper for one if the <tt>%copyctor</tt> is used.
- </li>
- <li>
- If a C++ class does not declare an explicit destructor, SWIG will
- automatically generate a wrapper for one.
- </li>
- </ul>
- <p>
- And as in C++, a few rules that alters the previous behavior:
- </p>
- <ul>
- <li>A default constructor is not created if a class already defines a constructor with arguments.
- </li>
- <li>Default constructors are not generated for classes with pure virtual methods or for classes that
- inherit from an abstract class, but don't provide definitions for all of the pure methods.
- </li>
- <li>A default constructor is not created unless all base classes support a
- default constructor.
- </li>
- <li>Default constructors and implicit destructors are not created if a class
- defines them in a <tt>private</tt> or <tt>protected</tt> section.
- </li>
- <li>Default constructors and implicit destructors are not created if any base
- class defines a non-public default constructor or destructor.
- </li>
- </ul>
- <p>
- SWIG should never generate a default constructor, copy constructor or
- default destructor wrapper for a class in which it is illegal to do so. In
- some cases, however, it could be necessary (if the complete class
- declaration is not visible from SWIG, and one of the above rules is
- violated) or desired (to reduce the size of the final interface) by
- manually disabling the implicit constructor/destructor generation.
- </p>
- <p>
- To manually disable these, the <tt>%nodefaultctor</tt> and <tt>%nodefaultdtor</tt>
- <a href="Customization.html#Customization_feature_flags">feature flag</a> directives
- can be used. Note that these directives only affects the
- implicit generation, and they have no effect if the default/copy
- constructors or destructor are explicitly declared in the class
- interface.
- </p>
- <p>
- For example:
- </p>
- <div class="code">
- <pre>
- %nodefaultctor Foo; // Disable the default constructor for class Foo.
- class Foo { // No default constructor is generated, unless one is declared
- ...
- };
- class Bar { // A default constructor is generated, if possible
- ...
- };
- </pre>
- </div>
- <p>
- The directive <tt>%nodefaultctor</tt> can also be applied "globally", as in:
- </p>
- <div class="code">
- <pre>
- %nodefaultctor; // Disable creation of default constructors
- class Foo { // No default constructor is generated, unless one is declared
- ...
- };
- class Bar {
- public:
- Bar(); // The default constructor is generated, since one is declared
- };
- %clearnodefaultctor; // Enable the creation of default constructors again
- </pre>
- </div>
- <p>
- The corresponding <tt>%nodefaultdtor</tt> directive can be used
- to disable the generation of the default or implicit destructor, if
- needed. Be aware, however, that this could lead to memory leaks in the
- target language. Hence, it is recommended to use this directive only
- in well known cases. For example:
- </p>
- <div class="code">
- <pre>
- %nodefaultdtor Foo; // Disable the implicit/default destructor for class Foo.
- class Foo { // No destructor is generated, unless one is declared
- ...
- };
- </pre>
- </div>
- <p>
- <b>Compatibility Note:</b> The generation of default
- constructors/implicit destructors was made the default behavior in SWIG
- 1.3.7. This may break certain older modules, but the old behavior can
- be easily restored using <tt>%nodefault</tt> or the
- <tt>-nodefault</tt> command line option. Furthermore, in order for
- SWIG to properly generate (or not generate) default constructors, it
- must be able to gather information from both the <tt>private</tt> and
- <tt>protected</tt> sections (specifically, it needs to know if a private or
- protected constructor/destructor is defined). In older versions of
- SWIG, it was fairly common to simply remove or comment out
- the private and protected sections of a class due to parser limitations.
- However, this removal may now cause SWIG to erroneously generate constructors
- for classes that define a constructor in those sections. Consider restoring
- those sections in the interface or using <tt>%nodefault</tt> to fix the problem.
- </p>
- <p>
- <b>Note:</b> The <tt>%nodefault</tt>
- directive/<tt>-nodefault</tt> options described above, which disable both the default
- constructor and the implicit destructors, could lead to memory
- leaks, and so it is strongly recommended to not use them.
- </p>
- <H3><a name="SWIGPlus_nn9"></a>6.6.3 When constructor wrappers aren't created</H3>
- <p>
- If a class defines a constructor, SWIG normally tries to generate a wrapper for it. However, SWIG will
- not generate a constructor wrapper if it thinks that it will result in illegal wrapper code. There are really
- two cases where this might show up.
- </p>
- <p>
- First, SWIG won't generate wrappers for protected or private constructors. For example:
- </p>
- <div class="code">
- <pre>
- class Foo {
- protected:
- Foo(); // Not wrapped.
- public:
- ...
- };
- </pre>
- </div>
- <p>
- Next, SWIG won't generate wrappers for a class if it appears to be abstract--that is, it has undefined
- pure virtual methods. Here are some examples:
- </p>
- <div class="code">
- <pre>
- class Bar {
- public:
- Bar(); // Not wrapped. Bar is abstract.
- virtual void spam(void) = 0;
- };
- class Grok : public Bar {
- public:
- Grok(); // Not wrapped. No implementation of abstract spam().
- };
- </pre>
- </div>
- <p>
- Some users are surprised (or confused) to find missing constructor wrappers in their interfaces. In almost
- all cases, this is caused when classes are determined to be abstract. To see if this is the case, run SWIG with
- all of its warnings turned on:
- </p>
- <div class="shell">
- <pre>
- % swig -Wall -python module.i
- </pre>
- </div>
- <p>
- In this mode, SWIG will issue a warning for all abstract classes. It is possible to force a class to be
- non-abstract using this:
- </p>
- <div class="code">
- <pre>
- %feature("notabstract") Foo;
- class Foo : public Bar {
- public:
- Foo(); // Generated no matter what---not abstract.
- ...
- };
- </pre>
- </div>
- <p>
- More information about <tt>%feature</tt> can be found in the <a href="Customization.html#Customization">Customization features</a> chapter.
- </p>
- <H3><a name="SWIGPlus_nn10"></a>6.6.4 Copy constructors</H3>
- <p>
- If a class defines more than one constructor, its behavior depends on the capabilities of the
- target language. If overloading is supported, the copy constructor is accessible using
- the normal constructor function. For example, if you have this:
- </p>
- <div class="code">
- <pre>
- class List {
- public:
- List();
- List(const List &); // Copy constructor
- ...
- };
- </pre>
- </div>
- <p>
- then the copy constructor can be used as follows:
- </p>
- <div class="targetlang">
- <pre>
- x = List() # Create a list
- y = List(x) # Copy list x
- </pre>
- </div>
- <p>
- If the target language does not support overloading, then the copy constructor is available
- through a special function like this:
- </p>
- <div class="code">
- <pre>
- List *copy_List(List *f) {
- return new List(*f);
- }
- </pre>
- </div>
- <p>
- <b>Note:</b> For a class <tt>X</tt>, SWIG only treats a constructor as
- a copy constructor if it can be applied to an object of type
- <tt>X</tt> or <tt>X *</tt>. If more than one copy constructor is
- defined, only the first definition that appears is used as the copy
- constructor--other definitions will result in a name-clash.
- Constructors such as <tt>X(const X &)</tt>, <tt>X(X &)</tt>, and
- <tt>X(X *)</tt> are handled as copy constructors in SWIG.
- </p>
- <p>
- <b>Note:</b> SWIG does <em>not</em> generate a copy constructor
- wrapper unless one is explicitly declared in the class. This differs
- from the treatment of default constructors and destructors.
- However, copy constructor wrappers can be generated if using the <tt>copyctor</tt>
- <a href="Customization.html#Customization_feature_flags">feature flag</a>. For example:
- </p>
- <div class="code">
- <pre>
- %copyctor List;
- class List {
- public:
- List();
- };
- </pre>
- </div>
- <p>
- Will generate a copy constructor wrapper for <tt>List</tt>.
- </p>
- <p>
- <b>Compatibility note:</b> Special support for copy constructors was
- not added until SWIG-1.3.12. In previous versions, copy constructors
- could be wrapped, but they had to be renamed. For example:
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- Foo();
- %name(CopyFoo) Foo(const Foo &);
- ...
- };
- </pre>
- </div>
- <p>
- For backwards compatibility, SWIG does not perform any special
- copy-constructor handling if the constructor has been manually
- renamed. For instance, in the above example, the name of the
- constructor is set to <tt>new_CopyFoo()</tt>. This is the same as in
- older versions.
- </p>
- <H3><a name="SWIGPlus_nn11"></a>6.6.5 Member functions</H3>
- <p>
- All member functions are roughly translated into accessor functions like this :</p>
- <div class="code"><pre>
- int List_search(List *obj, char *value) {
- return obj->search(value);
- }
- </pre></div>
- <p>
- This translation is the same even if the member function has been
- declared as <tt>virtual</tt>.
- </p>
- <p>
- It should be noted that SWIG does not <em>actually</em> create a C accessor
- function in the code it generates. Instead, member access such as
- <tt>obj->search(value)</tt> is directly inlined into the generated
- wrapper functions. However, the name and calling convention of the
- low-level procedural wrappers match the accessor function prototype described above.
- </p>
- <H3><a name="SWIGPlus_nn12"></a>6.6.6 Static members</H3>
- <p>
- Static member functions are called directly without making any special
- transformations. For example, the static member function
- <tt>print(List *l)</tt> directly invokes <tt>List::print(List *l)</tt>
- in the generated wrapper code.
- </p>
- <H3><a name="SWIGPlus_member_data"></a>6.6.7 Member data</H3>
- <p>
- Member data is handled in exactly the same manner as for C
- structures. A pair of accessor functions are effectively created. For example
- :</p>
- <div class="code"><pre>
- int List_length_get(List *obj) {
- return obj->length;
- }
- int List_length_set(List *obj, int value) {
- obj->length = value;
- return value;
- }
- </pre></div>
- <p>
- A read-only member can be created using the <tt>%immutable</tt> and <tt>%mutable</tt>
- <a href="Customization.html#Customization_feature_flags">feature flag</a> directive.
- For example, we probably wouldn't want
- the user to change the length of a list so we could do the following
- to make the value available, but read-only.</p>
- <div class="code"><pre>
- class List {
- public:
- ...
- %immutable;
- int length;
- %mutable;
- ...
- };
- </pre></div>
- <p>
- Alternatively, you can specify an immutable member in advance like this:
- </p>
- <div class="code">
- <pre>
- %immutable List::length;
- ...
- class List {
- ...
- int length; // Immutable by above directive
- ...
- };
- </pre>
- </div>
- <p>
- Similarly, all data attributes declared as <tt>const</tt> are wrapped as read-only members.
- </p>
- <p>
- There are some subtle issues when wrapping data members that are
- themselves classes. For instance, if you had another class like this,
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- List items;
- ...
- </pre>
- </div>
- <p>
- then the low-level accessor to the <tt>items</tt> member actually uses pointers. For example:
- </p>
- <div class="code">
- <pre>
- List *Foo_items_get(Foo *self) {
- return &self->items;
- }
- void Foo_items_set(Foo *self, List *value) {
- self->items = *value;
- }
- </pre>
- </div>
- <p>
- More information about this can be found in the SWIG Basics chapter,
- <a href="SWIG.html#SWIG_structure_data_members">Structure data members</a> section.
- </p>
- <p>
- The wrapper code to generate the accessors for classes comes from the pointer typemaps.
- This can be somewhat unnatural for some types.
- For example, a user would expect the STL std::string class member variables to be wrapped as a string in the target language,
- rather than a pointer to this class.
- The const reference typemaps offer this type of marshalling, so there is a feature to tell SWIG to use the const reference typemaps rather than the pointer typemaps.
- It is the <tt>%naturalvar</tt> directive and is used as follows:
- </p>
- <div class="code">
- <pre>
- // All List variables will use const List& typemaps
- %naturalvar List;
- // Only Foo::myList will use const List& typemaps
- %naturalvar Foo::myList;
- struct Foo {
- List myList;
- };
- // All variables will use const reference typemaps
- %naturalvar;
- </pre>
- </div>
- <p>
- The observant reader will notice that <tt>%naturalvar</tt> works like any other
- <a href="Customization.html#Customization_feature_flags">feature flag</a> directive,
- except it can also be attached to class types.
- The first of the example usages above show <tt>%naturalvar</tt> attaching to the <tt>List</tt> class.
- Effectively this feature changes the way accessors are generated to the following:
- </p>
- <div class="code">
- <pre>
- const List &Foo_items_get(Foo *self) {
- return self->items;
- }
- void Foo_items_set(Foo *self, const List &value) {
- self->items = value;
- }
- </pre>
- </div>
- <p>
- In fact it is generally a good idea to use this feature globally as the reference typemaps have extra NULL checking compared to the pointer typemaps.
- A pointer can be NULL, whereas a reference cannot, so the extra checking ensures that the target language user does not pass in a value that translates
- to a NULL pointer and thereby preventing any potential NULL pointer dereferences.
- The <tt>%naturalvar</tt> feature will apply to global variables in addition to member variables in some language modules, eg C# and Java.
- </p>
- <p>
- Other alternatives for turning this feature on globally are to use the <tt>swig -naturalvar</tt> commandline option
- or the module mode option, <tt>%module(naturalvar=1)</tt>
- </p>
- <p>
- <b>Compatibility note:</b> The <tt>%naturalvar</tt> feature was introduced in SWIG-1.3.28, prior to which it was necessary to manually apply the const reference
- typemaps, eg <tt>%apply const std::string & { std::string * }</tt>, but this example would also apply the typemaps to methods taking a <tt>std::string</tt> pointer.
- </p>
- <p>
- <b>Compatibility note:</b> Read-only access used to be controlled by a pair of directives
- <tt>%readonly</tt> and <tt>%readwrite</tt>. Although these directives still work, they
- generate a warning message. Simply change the directives to <tt>%immutable;</tt> and
- <tt>%mutable;</tt> to silence the warning. Don't forget the extra semicolon!
- </p>
- <p>
- <b>Compatibility note:</b> Prior to SWIG-1.3.12, all members of unknown type were
- wrapped into accessor functions using pointers. For example, if you had a structure
- like this
- </p>
- <div class="code">
- <pre>
- struct Foo {
- size_t len;
- };
- </pre>
- </div>
- <p>
- and nothing was known about <tt>size_t</tt>, then accessors would be
- written to work with <tt>size_t *</tt>. Starting in SWIG-1.3.12, this
- behavior has been modified. Specifically, pointers will <em>only</em>
- be used if SWIG knows that a datatype corresponds to a structure or
- class. Therefore, the above code would be wrapped into accessors
- involving <tt>size_t</tt>. This change is subtle, but it smooths over
- a few problems related to structure wrapping and some of SWIG's
- customization features.
- </p>
- <H2><a name="SWIGPlus_default_args"></a>6.7 Default arguments</H2>
- <p>
- SWIG will wrap all types of functions that have default arguments. For example member functions:
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- void bar(int x, int y = 3, int z = 4);
- };
- </pre>
- </div>
- <p>
- SWIG handles default arguments by generating an extra overloaded method for each defaulted argument.
- SWIG is effectively handling methods with default arguments as if it was wrapping the equivalent overloaded methods.
- Thus for the example above, it is as if we had instead given the following to SWIG:
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- void bar(int x, int y, int z);
- void bar(int x, int y);
- void bar(int x);
- };
- </pre>
- </div>
- <p>
- The wrappers produced are exactly the same as if the above code was instead fed into SWIG.
- Details of this are covered later in the <a href="#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods</a> section.
- This approach allows SWIG to wrap all possible default arguments, but can be verbose.
- For example if a method has ten default arguments, then eleven wrapper methods are generated.
- </p>
- <p>
- Please see the <a href="Customization.html#Customization_features_default_args">Features and default arguments</a>
- section for more information on using <tt>%feature</tt> with functions with default arguments.
- The <a href="#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section
- also deals with using <tt>%rename</tt> and <tt>%ignore</tt> on methods with default arguments.
- If you are writing your own typemaps for types used in methods with default arguments, you may also need to write a <tt>typecheck</tt> typemap.
- See the <a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a> section for details or otherwise
- use the <tt>compactdefaultargs</tt> feature flag as mentioned below.
- </p>
- <p>
- <b>Compatibility note:</b> Versions of SWIG prior to SWIG-1.3.23 wrapped default arguments slightly differently.
- Instead a single wrapper method was generated and the default values were copied into the C++ wrappers
- so that the method being wrapped was then called with all the arguments specified.
- If the size of the wrappers are a concern then this approach to wrapping methods with default arguments
- can be re-activated by using the <tt>compactdefaultargs</tt>
- <a href="Customization.html#Customization_feature_flags">feature flag</a>.
- </p>
- <div class="code">
- <pre>
- %feature("compactdefaultargs") Foo::bar;
- class Foo {
- public:
- void bar(int x, int y = 3, int z = 4);
- };
- </pre>
- </div>
- <p>
- This is great for reducing the size of the wrappers, but the caveat is it does not work for the statically typed languages,
- such as C# and Java,
- which don't have optional arguments in the language,
- Another restriction of this feature is that it cannot handle default arguments that are not public.
- The following example illustrates this:
- </p>
- <div class="code">
- <pre>
- class Foo {
- private:
- static const int spam;
- public:
- void bar(int x, int y = spam); // Won't work with %feature("compactdefaultargs") -
- // private default value
- };
- </pre>
- </div>
- <p>
- This produces uncompileable wrapper code because default values in C++ are
- evaluated in the same scope as the member function whereas SWIG
- evaluates them in the scope of a wrapper function (meaning that the
- values have to be public).
- </p>
- <p>
- This feature is automatically turned on when wrapping <a href="SWIG.html#SWIG_default_args">C code with default arguments</a>
- and whenever keyword arguments (kwargs) are specified for either C or C++ code.
- Keyword arguments are a language feature of some scripting languages, for example Ruby and Python.
- SWIG is unable to support kwargs when wrapping overloaded methods, so the default approach cannot be used.
- </p>
- <H2><a name="SWIGPlus_nn15"></a>6.8 Protection</H2>
- <p>
- SWIG wraps class members that are public following the C++
- conventions, i.e., by explicit public declaration or by the use of
- the <tt> using</tt> directive. In general, anything specified in a
- private or protected section will be ignored, although the internal
- code generator sometimes looks at the contents of the private and
- protected sections so that it can properly generate code for default
- constructors and destructors. Directors could also modify the way
- non-public virtual protected members are treated.
- </p>
- <p>
- By default, members of a class definition are assumed to be private
- until you explicitly give a `<tt>public:</tt>' declaration (This is
- the same convention used by C++).
- </p>
- <H2><a name="SWIGPlus_nn16"></a>6.9 Enums and constants</H2>
- <p>
- Enumerations and constants are handled differently by the different language modules and are described in detail in the appropriate language chapter.
- However, many languages map enums and constants in a class definition
- into constants with the classname as a prefix. For example :</p>
- <div class="code"><pre>
- class Swig {
- public:
- enum {ALE, LAGER, PORTER, STOUT};
- };
- </pre></div>
- <p>
- Generates the following set of constants in the target scripting language :</p>
- <div class="targetlang"><pre>
- Swig_ALE = Swig::ALE
- Swig_LAGER = Swig::LAGER
- Swig_PORTER = Swig::PORTER
- Swig_STOUT = Swig::STOUT
- </pre></div>
- <p>
- Members declared as <tt>const</tt> are wrapped as read-only members and do not create constants.
- </p>
- <H2><a name="SWIGPlus_nn17"></a>6.10 Friends</H2>
- <p>
- Friend declarations are recognised by SWIG. For example, if
- you have this code:
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- ...
- friend void blah(Foo *f);
- ...
- };
- </pre>
- </div>
- <p>
- then the <tt>friend</tt> declaration does result in a wrapper code
- equivalent to one generated for the following declaration
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- ...
- };
- void blah(Foo *f);
- </pre>
- </div>
- <p>
- A friend declaration, as in C++, is understood to be in the same scope
- where the class is declared, hence, you can have
- </p>
- <div class="code">
- <pre>
- %ignore bar::blah(Foo *f);
- namespace bar {
- class Foo {
- public:
- ...
- friend void blah(Foo *f);
- ...
- };
- }
- </pre>
- </div>
- <p>
- and a wrapper for the method 'blah' will not be generated.
- </p>
- <H2><a name="SWIGPlus_nn18"></a>6.11 References and pointers</H2>
- <p>
- C++ references are supported, but SWIG transforms them back into pointers. For example,
- a declaration like this :</p>
- <div class="code"><pre>
- class Foo {
- public:
- double bar(double &a);
- }
- </pre></div>
- <p>
- has a low-level accessor
- </p>
- <div class="code"><pre>
- double Foo_bar(Foo *obj, double *a) {
- obj->bar(*a);
- }
- </pre></div>
- <p>
- As a special case, most language modules pass <tt>const</tt> references to primitive datatypes (<tt>int</tt>, <tt>short</tt>,
- <tt>float</tt>, etc.) by value instead of pointers. For example, if you have a function like this,
- </p>
- <div class="code">
- <pre>
- void foo(const int &x);
- </pre>
- </div>
- <p>
- it is called from a script as follows:
- </p>
- <div class="targetlang">
- <pre>
- foo(3) # Notice pass by value
- </pre>
- </div>
- <p>
- Functions that return a reference are remapped to return a pointer instead.
- For example:
- </p>
- <div class="code"><pre>
- class Bar {
- public:
- Foo &spam();
- };
- </pre>
- </div>
- <p>
- Generates an accessor like this:
- </p>
- <div class="code">
- <pre>
- Foo *Bar_spam(Bar *obj) {
- Foo &result = obj->spam();
- return &result;
- }
- </pre>
- </div>
- <p>
- However, functions that return <tt>const</tt> references to primitive datatypes (<tt>int</tt>, <tt>short</tt>, etc.) normally
- return the result as a value rather than a pointer. For example, a function like this,
- </p>
- <div class="code">
- <pre>
- const int &bar();
- </pre>
- </div>
- <p>
- will return integers such as 37 or 42 in the target scripting language rather than a pointer to an integer.
- </p>
- <P>
- Don't return references to objects allocated as local variables on the
- stack. SWIG doesn't make a copy of the objects so this will probably
- cause your program to crash.
- <p>
- <b>Note:</b> The special treatment for references to primitive datatypes is necessary to provide
- more seamless integration with more advanced C++ wrapping applications---especially related to
- templates and the STL. This was first added in SWIG-1.3.12.
- </p>
- <H2><a name="SWIGPlus_nn19"></a>6.12 Pass and return by value</H2>
- <p>
- Occasionally, a C++ program will pass and return class objects by value. For example, a function
- like this might appear:
- </p>
- <div class="code">
- <pre>
- Vector cross_product(Vector a, Vector b);
- </pre>
- </div>
- <p>
- If no information is supplied about <tt>Vector</tt>, SWIG creates a wrapper function similar to the
- following:
- </p>
- <div class="code">
- <pre>
- Vector *wrap_cross_product(Vector *a, Vector *b) {
- Vector x = *a;
- Vector y = *b;
- Vector r = cross_product(x,y);
- return new Vector(r);
- }</pre>
- </div>
- <p>
- In order for the wrapper code to compile, <tt>Vector</tt> must define a copy constructor and a
- default constructor.
- </p>
- <p>
- If <tt>Vector</tt> is defined as a class in the interface, but it does not
- support a default constructor, SWIG changes the wrapper code by encapsulating
- the arguments inside a special C++ template wrapper class, through a process
- called the "Fulton Transform". This produces a wrapper that looks like this:
- </p>
- <div class="code">
- <pre>
- Vector cross_product(Vector *a, Vector *b) {
- SwigValueWrapper<Vector> x = *a;
- SwigValueWrapper<Vector> y = *b;
- SwigValueWrapper<Vector> r = cross_product(x,y);
- return new Vector(r);
- }
- </pre>
- </div>
- <p>
- This transformation is a little sneaky, but it provides support for
- pass-by-value even when a class does not provide a default constructor
- and it makes it possible to properly support a number of SWIG's
- customization options. The definition of <tt>SwigValueWrapper</tt>
- can be found by reading the SWIG wrapper code. This class is really nothing more than a thin
- wrapper around a pointer.
- </p>
- <p>
- Although SWIG usually detects the classes to which the Fulton Transform should
- be applied, in some situations it's necessary to override it. That's done with
- <tt>%feature("valuewrapper")</tt> to ensure it is used and <tt>%feature("novaluewrapper")</tt>
- to ensure it is not used:
- </p>
- <div class="code"><pre>
- %feature("novaluewrapper") A;
- class A;
- %feature("valuewrapper") B;
- struct B {
- B();
- // ....
- };
- </pre></div>
- <p>
- It is well worth considering turning this feature on for classes that do have a default constructor.
- It will remove a redundant constructor call at the point of the variable declaration in the wrapper,
- so will generate notably better performance for large objects or for classes with expensive construction.
- Alternatively consider returning a reference or a pointer.
- </p>
- <p>
- <b>Note:</b> this transformation has no effect on typemaps
- or any other part of SWIG---it should be transparent except that you
- may see this code when reading the SWIG output file.
- </p>
- <p>
- <b>
- Note: </b>This template transformation is new in SWIG-1.3.11 and may be refined in
- future SWIG releases. In practice, it is only absolutely necessary to do this for
- classes that don't define a default constructor.
- </p>
- <p>
- <b>Note:</b> The use of this template only occurs when objects are passed or returned by value.
- It is not used for C++ pointers or references.
- </p>
- <H2><a name="SWIGPlus_nn20"></a>6.13 Inheritance</H2>
- <p>
- SWIG supports C++ inheritance of classes and allows both single and
- multiple inheritance, as limited or allowed by the target
- language. The SWIG type-checker knows about the relationship between
- base and derived classes and allows pointers to any object of a
- derived class to be used in functions of a base class. The
- type-checker properly casts pointer values and is safe to use with
- multiple inheritance.
- </p>
- <p> SWIG treats private or protected inheritance as close to the C++
- spirit, and target language capabilities, as possible. In most
- cases, this means that SWIG will parse the non-public inheritance
- declarations, but that will have no effect in the generated code,
- besides the implicit policies derived for constructor and
- destructors.
- </p>
- <p>
- The following example shows how SWIG handles inheritance. For clarity,
- the full C++ code has been omitted.</p>
- <div class="code"><pre>
- // shapes.i
- %module shapes
- %{
- #include "shapes.h"
- %}
- class Shape {
- public:
- double x,y;
- virtual double area() = 0;
- virtual double perimeter() = 0;
- void set_location(double x, double y);
- };
- class Circle : public Shape {
- public:
- Circle(double radius);
- ~Circle();
- double area();
- double perimeter();
- };
- class Square : public Shape {
- public:
- Square(double size);
- ~Square();
- double area();
- double perimeter();
- }
- </pre></div>
- <p>
- When wrapped into Python, we can perform the following operations (shown using the low level Python accessors):
- </p>
- <div class="targetlang"><pre>
- $ python
- >>> import shapes
- >>> circle = shapes.new_Circle(7)
- >>> square = shapes.new_Square(10)
- >>> print shapes.Circle_area(circle)
- 153.93804004599999757
- >>> print shapes.Shape_area(circle)
- 153.93804004599999757
- >>> print shapes.Shape_area(square)
- 100.00000000000000000
- >>> shapes.Shape_set_location(square,2,-3)
- >>> print shapes.Shape_perimeter(square)
- 40.00000000000000000
- >>>
- </pre></div>
- <p>
- In this example, Circle and Square objects have been created. Member
- functions can be invoked on each object by making calls to
- <tt>Circle_area</tt>, <tt>Square_area</tt>, and so on. However, the same
- results can be accomplished by simply using the <tt>Shape_area</tt>
- function on either object.
- </p>
- <p>
- One important point concerning inheritance is that the low-level
- accessor functions are only generated for classes in which they are
- actually declared. For instance, in the above example, the method
- <tt>set_location()</tt> is only accessible as
- <tt>Shape_set_location()</tt> and not as
- <tt>Circle_set_location()</tt> or <tt>Square_set_location()</tt>. Of
- course, the <tt>Shape_set_location()</tt> function will accept any
- kind of object derived from Shape. Similarly, accessor functions for
- the attributes <tt>x</tt> and <tt>y</tt> are generated as
- <tt>Shape_x_get()</tt>, <tt>Shape_x_set()</tt>,
- <tt>Shape_y_get()</tt>, and <tt>Shape_y_set()</tt>. Functions such as
- <tt>Circle_x_get()</tt> are not available--instead you should use
- <tt>Shape_x_get()</tt>.
- </p>
- <p>
- Note that there is a one to one correlation between the low-level accessor functions and
- the proxy methods and therefore there is also a one to one correlation between
- the C++ class methods and the generated proxy class methods.
- </p>
- <p>
- <b>Note:</b> For the best results, SWIG requires all
- base classes to be defined in an interface. Otherwise, you may get a
- warning message like this:
- </p>
- <div class="shell">
- <pre>
- example.i:18: Warning(401): Nothing known about base class 'Foo'. Ignored.
- </pre>
- </div>
- <p>
- If any base class is undefined, SWIG still generates correct type
- relationships. For instance, a function accepting a <tt>Foo *</tt>
- will accept any object derived from <tt>Foo</tt> regardless of whether
- or not SWIG actually wrapped the <tt>Foo</tt> class. If you really
- don't want to generate wrappers for the base class, but you want to
- silence the warning, you might consider using the <tt>%import</tt>
- directive to include the file that defines <tt>Foo</tt>.
- <tt>%import</tt> simply gathers type information, but doesn't generate
- wrappers. Alternatively, you could just define <tt>Foo</tt> as an empty class
- in the SWIG interface or use
- <a href="Warnings.html#Warnings_suppression">warning suppression</a>.
- </p>
- <p>
- <b>Note:</b> <tt>typedef</tt>-names <em>can</em> be used as base classes. For example:
- </p>
- <div class="code">
- <pre>
- class Foo {
- ...
- };
- typedef Foo FooObj;
- class Bar : public FooObj { // Ok. Base class is Foo
- ...
- };
- </pre>
- </div>
- <p>
- Similarly, <tt>typedef</tt> allows unnamed structures to be used as base classes. For example:
- </p>
- <div class="code">
- <pre>
- typedef struct {
- ...
- } Foo;
- class Bar : public Foo { // Ok.
- ...
- };
- </pre>
- </div>
- <p>
- <b>Compatibility Note:</b> Starting in version 1.3.7, SWIG only
- generates low-level accessor wrappers for the declarations that are
- actually defined in each class. This differs from SWIG1.1 which used
- to inherit all of the declarations defined in base classes and
- regenerate specialized accessor functions such as
- <tt>Circle_x_get()</tt>, <tt>Square_x_get()</tt>,
- <tt>Circle_set_location()</tt>, and <tt>Square_set_location()</tt>.
- This behavior resulted in huge amounts of replicated code for large
- class hierarchies and made it awkward to build applications spread
- across multiple modules (since accessor functions are duplicated in
- every single module). It is also unnecessary to have such wrappers
- when advanced features like proxy classes are used.
- <b>Note:</b> Further optimizations are enabled when using the
- <tt>-fvirtual</tt> option, which avoids the regenerating of wrapper
- functions for virtual members that are already defined in a base
- class.
- </p>
- <H2><a name="SWIGPlus_nn21"></a>6.14 A brief discussion of multiple inheritance, pointers, and type checking</H2>
- <p>
- When a target scripting language refers to a C++ object, it normally
- uses a tagged pointer object that contains both the value of the
- pointer and a type string. For example, in Tcl, a C++ pointer might
- be encoded as a string like this:
- </p>
- <div class="diagram">
- <pre>
- _808fea88_p_Circle
- </pre>
- </div>
- <p>
- A somewhat common question is whether or not the type-tag could be safely
- removed from the pointer. For instance, to get better performance, could you
- strip all type tags and just use simple integers instead?
- </p>
- <p>
- In general, the answer to this question is no. In the wrappers, all
- pointers are converted into a common data representation in the target
- language. Typically this is the equivalent of casting a pointer to <tt>void *</tt>.
- This means that any C++ type information associated with the pointer is
- lost in the conversion.
- </p>
- <p>
- The problem with losing type information is that it is needed to
- properly support many advanced C++ features--especially multiple
- inheritance. For example, suppose you had code like this:
- </p>
- <div class="code">
- <pre>
- class A {
- public:
- int x;
- };
- class B {
- public:
- int y;
- };
- class C : public A, public B {
- };
- int A_function(A *a) {
- return a->x;
- }
- int B_function(B *b) {
- return b->y;
- }
- </pre>
- </div>
- <p>
- Now, consider the following code that uses <tt>void *</tt>.
- </p>
- <div class="code">
- <pre>
- C *c = new C();
- void *p = (void *) c;
- ...
- int x = A_function((A *) p);
- int y = B_function((B *) p);
- </pre>
- </div>
- <p>
- In this code, both <tt>A_function()</tt> and <tt>B_function()</tt> may
- legally accept an object of type <tt>C *</tt> (via inheritance).
- However, one of the functions will always return the wrong result when
- used as shown. The reason for this is that even though <tt>p</tt>
- points to an object of type <tt>C</tt>, the casting operation doesn't
- work like you would expect. Internally, this has to do with the data
- representation of <tt>C</tt>. With multiple inheritance, the data from
- each base class is stacked together. For example:
- </p>
- <div class="diagram">
- <pre>
- ------------ <--- (C *), (A *)
- | A |
- |------------| <--- (B *)
- | B |
- ------------
- </pre>
- </div>
- <p>
- Because of this stacking, a pointer of type <tt>C *</tt> may change
- value when it is converted to a <tt>A *</tt> or <tt>B *</tt>.
- However, this adjustment does <em>not</em> occur if you are converting from a
- <tt>void *</tt>.
- </p>
- <p>
- The use of type tags marks all pointers with the real type of the
- underlying object. This extra information is then used by SWIG
- generated wrappers to correctly cast pointer values under inheritance
- (avoiding the above problem).
- </p>
- <p>
- Some of the language modules are able to solve the problem by storing multiple instances of the pointer, for example, <tt>A *</tt>,
- in the A proxy class as well as <tt>C *</tt> in the C proxy class. The correct cast can then be made by choosing the correct <tt>void *</tt>
- pointer to use and is guaranteed to work as the cast to a void pointer and back to the same type does not lose any type information:
- </p>
- <div class="code">
- <pre>
- C *c = new C();
- void *p = (void *) c;
- void *pA = (void *) c;
- void *pB = (void *) c;
- ...
- int x = A_function((A *) pA);
- int y = B_function((B *) pB);
- </pre>
- </div>
- <p>
- In practice, the pointer is held as an integral number in the target language proxy class.
- </p>
- <H2><a name="SWIGPlus_overloaded_methods"></a>6.15 Wrapping Overloaded Functions and Methods</H2>
- <p>
- In many language modules, SWIG provides partial support for overloaded functions, methods, and
- constructors. For example, if you supply SWIG with overloaded functions like this:
- </p>
- <div class="code">
- <pre>
- void foo(int x) {
- printf("x is %d\n", x);
- }
- void foo(char *x) {
- printf("x is '%s'\n", x);
- }
- </pre>
- </div>
- <p>
- The function is used in a completely natural way. For example:
- </p>
- <div class="targetlang">
- <pre>
- >>> foo(3)
- x is 3
- >>> foo("hello")
- x is 'hello'
- >>>
- </pre>
- </div>
- <p>
- Overloading works in a similar manner for methods and constructors. For example if you have
- this code,
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- Foo();
- Foo(const Foo &); // Copy constructor
- void bar(int x);
- void bar(char *s, int y);
- };
- </pre>
- </div>
- <p>
- it might be used like this
- </p>
- <div class="targetlang">
- <pre>
- >>> f = Foo() # Create a Foo
- >>> f.bar(3)
- >>> g = Foo(f) # Copy Foo
- >>> f.bar("hello",2)
- </pre>
- </div>
- <H3><a name="SWIGPlus_nn24"></a>6.15.1 Dispatch function generation</H3>
- <p>
- The implementation of overloaded functions and methods is somewhat
- complicated due to the dynamic nature of scripting languages. Unlike
- C++, which binds overloaded methods at compile time, SWIG must
- determine the proper function as a runtime check for scripting language targets. This check is
- further complicated by the typeless nature of certain scripting languages. For instance,
- in Tcl, all types are simply strings. Therefore, if you have two overloaded functions
- like this,
- </p>
- <div class="code">
- <pre>
- void foo(char *x);
- void foo(int x);
- </pre>
- </div>
- <p>
- the order in which the arguments are checked plays a rather critical role.
- </p>
- <p>
- For statically typed languages, SWIG uses the language's method overloading mechanism.
- To implement overloading for the scripting languages, SWIG generates a dispatch function that checks the
- number of passed arguments and their types. To create this function, SWIG
- first examines all of the overloaded methods and ranks them according
- to the following rules:
- </p>
- <ol>
- <li><b>Number of required arguments.</b> Methods are sorted by increasing number of
- required arguments.
- </li>
- <li><p><b>Argument type precedence.</b> All C++ datatypes are assigned a numeric type precedence value
- (which is determined by the language module).</p>
- <div class="diagram">
- <pre>
- Type Precedence
- ---------------- ----------
- TYPE * 0 (High)
- void * 20
- Integers 40
- Floating point 60
- char 80
- Strings 100 (Low)
- </pre>
- </div>
- <p>
- Using these precedence values, overloaded methods with the same number of required arguments are sorted in increased
- order of precedence values.
- </p>
- </li>
- </ol>
- <p>
- This may sound very confusing, but an example will help. Consider the following collection of
- overloaded methods:
- </p>
- <div class="code">
- <pre>
- void foo(double);
- void foo(int);
- void foo(Bar *);
- void foo();
- void foo(int x, int y, int z, int w);
- void foo(int x, int y, int z = 3);
- void foo(double x, double y);
- void foo(double x, Bar *z);
- </pre>
- </div>
- <p>
- The first rule simply ranks the functions by required argument count.
- This would produce the following list:
- </p>
- <div class="diagram">
- <pre>
- rank
- -----
- [0] foo()
- [1] foo(double);
- [2] foo(int);
- [3] foo(Bar *);
- [4] foo(int x, int y, int z = 3);
- [5] foo(double x, double y)
- [6] foo(double x, Bar *z)
- [7] foo(int x, int y, int z, int w);
- </pre>
- </div>
- <p>
- The second rule, simply refines the ranking by looking at argument type precedence values.
- </p>
- <div class="diagram">
- <pre>
- rank
- -----
- [0] foo()
- [1] foo(Bar *);
- [2] foo(int);
- [3] foo(double);
- [4] foo(int x, int y, int z = 3);
- [5] foo(double x, Bar *z)
- [6] foo(double x, double y)
- [7] foo(int x, int y, int z, int w);
- </pre>
- </div>
- <p>
- Finally, to generate the dispatch function, the arguments passed to an overloaded method are simply
- checked in the same order as they appear in this ranking.
- </p>
- <p>
- If you're still confused, don't worry about it---SWIG is probably doing the right thing.
- </p>
- <H3><a name="SWIGPlus_nn25"></a>6.15.2 Ambiguity in Overloading</H3>
- <p>
- Regrettably, SWIG is not able to support every possible use of valid C++ overloading. Consider
- the following example:
- </p>
- <div class="code">
- <pre>
- void foo(int x);
- void foo(long x);
- </pre>
- </div>
- <p>
- In C++, this is perfectly legal. However, in a scripting language, there is generally only one kind of integer
- object. Therefore, which one of these functions do you pick? Clearly, there is no way to truly make a distinction
- just by looking at the value of the integer itself (<tt>int</tt> and <tt>long</tt> may even be the same precision).
- Therefore, when SWIG encounters this situation, it may generate a warning message like this for scripting languages:
- </p>
- <div class="shell">
- <pre>
- example.i:4: Warning(509): Overloaded foo(long) is shadowed by foo(int) at example.i:3.
- </pre>
- </div>
- <p>
- or for statically typed languages like Java:
- </p>
- <div class="shell">
- <pre>
- example.i:4: Warning(516): Overloaded method foo(long) ignored. Method foo(int)
- at example.i:3 used.
- </pre>
- </div>
- <p>
- This means that the second overloaded function will be inaccessible
- from a scripting interface or the method won't be wrapped at all.
- This is done as SWIG does not know how to disambiguate it from an earlier method.
- </p>
- <p>
- Ambiguity problems are known to arise in the following situations:
- </p>
- <ul>
- <li>Integer conversions. Datatypes such as <tt>int</tt>, <tt>long</tt>, and <tt>short</tt> cannot be disambiguated in some languages. Shown above.
- </li>
- <li>Floating point conversion. <tt>float</tt> and <tt>double</tt> can not be disambiguated in some languages.
- </li>
- <li>Pointers and references. For example, <tt>Foo *</tt> and <tt>Foo &</tt>.
- </li>
- <li>Pointers and arrays. For example, <tt>Foo *</tt> and <tt>Foo [4]</tt>.
- </li>
- <li>Pointers and instances. For example, <tt>Foo</tt> and <tt>Foo *</tt>. Note: SWIG converts all
- instances to pointers.
- </li>
- <li>Qualifiers. For example, <tt>const Foo *</tt> and <tt>Foo *</tt>.
- </li>
- <li>Default vs. non default arguments. For example, <tt>foo(int a, int b)</tt> and <tt>foo(int a, int b = 3)</tt>.
- </li>
- </ul>
- <p>
- When an ambiguity arises, methods are checked in the same order as they appear in the interface file.
- Therefore, earlier methods will shadow methods that appear later.
- </p>
- <p>
- When wrapping an overloaded function, there is a chance that you will get an error message like this:
- </p>
- <div class="shell">
- <pre>
- example.i:3: Warning(467): Overloaded foo(int) not supported (no type checking
- rule for 'int').
- </pre>
- </div>
- <p>
- This error means that the target language module supports overloading,
- but for some reason there is no type-checking rule that can be used to
- generate a working dispatch function. The resulting behavior is then
- undefined. You should report this as a bug to the
- <a href="http://www.swig.org/bugs.html">SWIG bug tracking database</a>.
- </p>
- <p>
- If you get an error message such as the following,
- </p>
- <div class="shell">
- <pre>
- foo.i:6. Overloaded declaration ignored. Spam::foo(double )
- foo.i:5. Previous declaration is Spam::foo(int )
- foo.i:7. Overloaded declaration ignored. Spam::foo(Bar *,Spam *,int )
- foo.i:5. Previous declaration is Spam::foo(int )
- </pre>
- </div>
- <p>
- it means that the target language module has not yet implemented support for overloaded
- functions and methods. The only way to fix the problem is to read the next section.
- </p>
- <H3><a name="ambiguity_resolution_renaming"></a>6.15.3 Ambiguity resolution and renaming</H3>
- <p>
- If an ambiguity in overload resolution occurs or if a module doesn't
- allow overloading, there are a few strategies for dealing with the
- problem. First, you can tell SWIG to ignore one of the methods. This
- is easy---simply use the <tt>%ignore</tt> directive. For example:
- </p>
- <div class="code">
- <pre>
- %ignore foo(long);
- void foo(int);
- void foo(long); // Ignored. Oh well.
- </pre>
- </div>
- <p>
- The other alternative is to rename one of the methods. This can be
- done using <tt>%rename</tt>. For example:
- </p>
- <div class="code">
- <pre>
- %rename("foo_short") foo(short);
- %rename(foo_long) foo(long);
- void foo(int);
- void foo(short); // Accessed as foo_short()
- void foo(long); // Accessed as foo_long()
- </pre>
- </div>
- <p>
- Note that the quotes around the new name are optional, however,
- should the new name be a C/C++ keyword they would be essential in order to avoid a parsing error.
- The <tt>%ignore</tt> and <tt>%rename</tt> directives are both rather powerful
- in their ability to match declarations. When used in their simple form, they apply to
- both global functions and methods. For example:
- </p>
- <div class="code">
- <pre>
- /* Forward renaming declarations */
- %rename(foo_i) foo(int);
- %rename(foo_d) foo(double);
- ...
- void foo(int); // Becomes 'foo_i'
- void foo(char *c); // Stays 'foo' (not renamed)
- class Spam {
- public:
- void foo(int); // Becomes 'foo_i'
- void foo(double); // Becomes 'foo_d'
- ...
- };
- </pre>
- </div>
- <p>
- If you only want the renaming to apply to a certain scope, the C++ scope resolution operator (::) can be used.
- For example:
- </p>
- <div class="code">
- <pre>
- %rename(foo_i) ::foo(int); // Only rename foo(int) in the global scope.
- // (will not rename class members)
- %rename(foo_i) Spam::foo(int); // Only rename foo(int) in class Spam
- </pre>
- </div>
- <p>
- When a renaming operator is applied to a class as in <tt>Spam::foo(int)</tt>, it is applied to
- that class and all derived classes. This can be used to apply a consistent renaming across
- an entire class hierarchy with only a few declarations. For example:
- </p>
- <div class="code">
- <pre>
- %rename(foo_i) Spam::foo(int);
- %rename(foo_d) Spam::foo(double);
- class Spam {
- public:
- virtual void foo(int); // Renamed to foo_i
- virtual void foo(double); // Renamed to foo_d
- ...
- };
- class Bar : public Spam {
- public:
- virtual void foo(int); // Renamed to foo_i
- virtual void foo(double); // Renamed to foo_d
- ...
- };
- class Grok : public Bar {
- public:
- virtual void foo(int); // Renamed to foo_i
- virtual void foo(double); // Renamed to foo_d
- ...
- };
- </pre>
- </div>
- <p>
- It is also possible to include <tt>%rename</tt> specifications in the
- class definition itself. For example:
- </p>
- <div class="code">
- <pre>
- class Spam {
- %rename(foo_i) foo(int);
- %rename(foo_d) foo(double);
- public:
- virtual void foo(int); // Renamed to foo_i
- virtual void foo(double); // Renamed to foo_d
- ...
- };
- class Bar : public Spam {
- public:
- virtual void foo(int); // Renamed to foo_i
- virtual void foo(double); // Renamed to foo_d
- ...
- };
- </pre>
- </div>
- <p>
- In this case, the <tt>%rename</tt> directives still get applied across the entire
- inheritance hierarchy, but it's no longer necessary to explicitly specify the
- class prefix <tt>Spam::</tt>.
- </p>
- <p>
- A special form of <tt>%rename</tt> can be used to apply a renaming just to class
- members (of all classes):
- </p>
- <div class="code">
- <pre>
- %rename(foo_i) *::foo(int); // Only rename foo(int) if it appears in a class.
- </pre>
- </div>
- <p>
- Note: the <tt>*::</tt> syntax is non-standard C++, but the '*' is meant to be a
- wildcard that matches any class name (we couldn't think of a better
- alternative so if you have a better idea, send email to
- the <a href="http://www.swig.org/mail.html">swig-devel mailing list</a>.
- </p>
- <p>
- Although this discussion has primarily focused on <tt>%rename</tt> all of the same rules
- also apply to <tt>%ignore</tt>. For example:
- </p>
- <div class="code">
- <pre>
- %ignore foo(double); // Ignore all foo(double)
- %ignore Spam::foo; // Ignore foo in class Spam
- %ignore Spam::foo(double); // Ignore foo(double) in class Spam
- %ignore *::foo(double); // Ignore foo(double) in all classes
- </pre>
- </div>
- <p>
- When applied to a base class, <tt>%ignore</tt> forces all definitions in derived classes
- to disappear. For example, <tt>%ignore Spam::foo(double)</tt> will eliminate <tt>foo(double)</tt> in
- <tt>Spam</tt> and all classes derived from <tt>Spam</tt>.
- </p>
- <p>
- <b>Notes on %rename and %ignore:</b>
- </p>
- <ul>
- <li><p>Since, the <tt>%rename</tt> declaration is used to declare a renaming in advance, it can be
- placed at the start of an interface file. This makes it possible to apply a consistent name
- resolution without having to modify header files. For example:</p>
- <div class="code">
- <pre>
- %module foo
- /* Rename these overloaded functions */
- %rename(foo_i) foo(int);
- %rename(foo_d) foo(double);
- %include "header.h"
- </pre>
- </div>
- </li>
- <li><p>The scope qualifier (::) can also be used on simple names. For example:</p>
- <div class="code">
- <pre>
- %rename(bar) ::foo; // Rename foo to bar in global scope only
- %rename(bar) Spam::foo; // Rename foo to bar in class Spam only
- %rename(bar) *::foo; // Rename foo in classes only
- </pre>
- </div>
- </li>
- <li><p>Name matching tries to find the most specific match that is
- defined. A qualified name such as <tt>Spam::foo</tt> always has
- higher precedence than an unqualified name <tt>foo</tt>.
- <tt>Spam::foo</tt> has higher precedence than <tt>*::foo</tt> and
- <tt>*::foo</tt> has higher precedence than <tt>foo</tt>. A
- parameterized name has higher precedence than an unparameterized name
- within the same scope level. However, an unparameterized name with a
- scope qualifier has higher precedence than a parameterized name in
- global scope (e.g., a renaming of <tt>Spam::foo</tt> takes precedence
- over a renaming of <tt>foo(int)</tt>).</p>
- </li>
- <li><p>
- The order in which <tt>%rename</tt> directives are defined does not matter
- as long as they appear before the declarations to be renamed. Thus, there is no difference
- between saying:</p>
- <div class="code">
- <pre>
- %rename(bar) foo;
- %rename(foo_i) Spam::foo(int);
- %rename(Foo) Spam::foo;
- </pre>
- </div>
- <p>
- and this
- </p>
- <div class="code">
- <pre>
- %rename(Foo) Spam::foo;
- %rename(bar) foo;
- %rename(foo_i) Spam::foo(int);
- </pre>
- </div>
- <p>
- (the declarations are not stored in a linked list and order has no
- importance). Of course, a repeated <tt>%rename</tt> directive will
- change the setting for a previous <tt>%rename</tt> directive if exactly the
- same name, scope, and parameters are supplied.
- </p>
- </li>
- <li>For multiple inheritance where renaming rules are defined for multiple base classes,
- the first renaming rule found on a depth-first traversal of the class hierarchy
- is used.
- </li>
- <li><p>The name matching rules strictly follow member qualification rules.
- For example, if you have a class like this:</p>
- <div class="code">
- <pre>
- class Spam {
- public:
- ...
- void bar() const;
- ...
- };
- </pre>
- </div>
- <p>
- the declaration
- </p>
- <div class="code">
- <pre>
- %rename(name) Spam::bar();
- </pre>
- </div>
- <p>
- will not apply as there is no unqualified member <tt>bar()</tt>. The following will apply as
- the qualifier matches correctly:
- </p>
- <div class="code">
- <pre>
- %rename(name) Spam::bar() const;
- </pre>
- </div>
- <p>
- An often overlooked C++ feature is that classes can define two different overloaded members
- that differ only in their qualifiers, like this:
- </p>
- <div class="code">
- <pre>
- class Spam {
- public:
- ...
- void bar(); // Unqualified member
- void bar() const; // Qualified member
- ...
- };
- </pre>
- </div>
- <p>
- %rename can then be used to target each of the overloaded methods individually.
- For example we can give them separate names in the target language:
- </p>
- <div class="code">
- <pre>
- %rename(name1) Spam::bar();
- %rename(name2) Spam::bar() const;
- </pre>
- </div>
- <p>
- Similarly, if you
- merely wanted to ignore one of the declarations, use <tt>%ignore</tt>
- with the full qualification. For example, the following directive
- would tell SWIG to ignore the <tt>const</tt> version of <tt>bar()</tt>
- above:
- </p>
- <div class="code">
- <pre>
- %ignore Spam::bar() const; // Ignore bar() const, but leave other bar() alone
- </pre>
- </div>
- </li>
- <li><p>
- Currently no resolution is performed in order to match function parameters. This means function parameter types must match exactly.
- For example, namespace qualifiers and typedefs will not work. The following usage of typedefs demonstrates this:
- <div class="code">
- <pre>
- typedef int Integer;
- %rename(foo_i) foo(int);
- class Spam {
- public:
- void foo(Integer); // Stays 'foo' (not renamed)
- };
- class Ham {
- public:
- void foo(int); // Renamed to foo_i
- };
- </pre>
- </div>
- <li><p>
- The name matching rules also use default arguments for finer control when wrapping methods that have default arguments.
- Recall that methods with default arguments are wrapped as if the equivalent overloaded methods had been parsed
- (<a href="#SWIGPlus_default_args">Default arguments</a> section).
- Let's consider the following example class:</p>
- <div class="code">
- <pre>
- class Spam {
- public:
- ...
- void bar(int i=-1, double d=0.0);
- ...
- };
- </pre>
- </div>
- <p>
- The following <tt>%rename</tt> will match exactly and apply to all the target language overloaded methods because the declaration with the default arguments
- exactly matches the wrapped method:
- </p>
- <div class="code">
- <pre>
- %rename(newbar) Spam::bar(int i=-1, double d=0.0);
- </pre>
- </div>
- <p>
- The C++ method can then be called from the target language with the new name no matter how many arguments are specified, for example:
- <tt>newbar(2, 2.0)</tt>, <tt>newbar(2)</tt> or <tt>newbar()</tt>.
- However, if the <tt>%rename</tt> does not contain the default arguments, it will only apply to the single equivalent target language overloaded method.
- So if instead we have:
- </p>
- <div class="code">
- <pre>
- %rename(newbar) Spam::bar(int i, double d);
- </pre>
- </div>
- <p>
- The C++ method must then be called from the target language with the new name <tt>newbar(2, 2.0)</tt> when both arguments are supplied
- or with the original name as <tt>bar(2)</tt> (one argument) or <tt>bar()</tt> (no arguments).
- In fact it is possible to use <tt>%rename</tt> on the equivalent overloaded methods, to rename all the equivalent overloaded methods:
- </p>
- <div class="code">
- <pre>
- %rename(bar_2args) Spam::bar(int i, double d);
- %rename(bar_1arg) Spam::bar(int i);
- %rename(bar_default) Spam::bar();
- </pre>
- </div>
- <p>
- Similarly, the extra overloaded methods can be selectively ignored using <tt>%ignore</tt>.
- </p>
- <p>
- <b>Compatibility note:</b> The <tt>%rename</tt> directive introduced the default argument matching rules in SWIG-1.3.23 at the same time as the changes
- to wrapping methods with default arguments was introduced.
- </p>
- </li>
- </ul>
- <H3><a name="SWIGPlus_nn27"></a>6.15.4 Comments on overloading</H3>
- <p>
- Support for overloaded methods was first added in SWIG-1.3.14. The implementation
- is somewhat unusual when compared to similar tools. For instance, the order in which
- declarations appear is largely irrelevant in SWIG. Furthermore, SWIG does not rely
- upon trial execution or exception handling to figure out which method to invoke.
- </p>
- <p>
- Internally, the overloading mechanism is completely configurable by the target language
- module. Therefore, the degree of overloading support may vary from language to language.
- As a general rule, statically typed languages like Java are able to provide more support
- than dynamically typed languages like Perl, Python, Ruby, and Tcl.
- </p>
- <H2><a name="SWIGPlus_nn28"></a>6.16 Wrapping overloaded operators</H2>
- <p>
- C++ overloaded operator declarations can be wrapped.
- For example, consider a class like this:
- </p>
- <div class="code">
- <pre>
- class Complex {
- private:
- double rpart, ipart;
- public:
- Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { }
- Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { }
- Complex &operator=(const Complex &c) {
- rpart = c.rpart;
- ipart = c.ipart;
- return *this;
- }
- Complex operator+(const Complex &c) const {
- return Complex(rpart+c.rpart, ipart+c.ipart);
- }
- Complex operator-(const Complex &c) const {
- return Complex(rpart-c.rpart, ipart-c.ipart);
- }
- Complex operator*(const Complex &c) const {
- return Complex(rpart*c.rpart - ipart*c.ipart,
- rpart*c.ipart + c.rpart*ipart);
- }
- Complex operator-() const {
- return Complex(-rpart, -ipart);
- }
- double re() const { return rpart; }
- double im() const { return ipart; }
- };
- </pre>
- </div>
- <p>
- When operator declarations appear, they are handled in
- <em>exactly</em> the same manner as regular methods. However, the
- names of these methods are set to strings like "<tt>operator +</tt>"
- or "<tt>operator -</tt>". The problem with these names is that they
- are illegal identifiers in most scripting languages. For instance,
- you can't just create a method called "<tt>operator +</tt>" in
- Python--there won't be any way to call it.
- </p>
- <p>
- Some language modules already know how to automatically handle certain
- operators (mapping them into operators in the target language).
- However, the underlying implementation of this is really managed in a
- very general way using the <tt>%rename</tt> directive. For example,
- in Python a declaration similar to this is used:
- </p>
- <div class="code">
- <pre>
- %rename(__add__) Complex::operator+;
- </pre>
- </div>
- <p>
- This binds the + operator to a method called <tt>__add__</tt> (which
- is conveniently the same name used to implement the Python + operator).
- Internally, the generated wrapper code for a wrapped operator will look
- something like this pseudocode:
- </p>
- <div class="code">
- <pre>
- _wrap_Complex___add__(args) {
- ... get args ...
- obj->operator+(args);
- ...
- }
- </pre>
- </div>
- <p>
- When used in the target language, it may now be possible to use the overloaded
- operator normally. For example:
- </p>
- <div class="targetlang">
- <pre>
- >>> a = Complex(3,4)
- >>> b = Complex(5,2)
- >>> c = a + b # Invokes __add__ method
- </pre>
- </div>
- <p>
- It is important to realize that there is nothing magical happening
- here. The <tt>%rename</tt> directive really only picks a valid method
- name. If you wrote this:
- </p>
- <div class="code">
- <pre>
- %rename(add) operator+;
- </pre>
- </div>
- <p>
- The resulting scripting interface might work like this:
- </p>
- <div class="targetlang">
- <pre>
- a = Complex(3,4)
- b = Complex(5,2)
- c = a.add(b) # Call a.operator+(b)
- </pre>
- </div>
- <p>
- All of the techniques described to deal with overloaded functions also
- apply to operators. For example:
- </p>
- <div class="code">
- <pre>
- %ignore Complex::operator=; // Ignore = in class Complex
- %ignore *::operator=; // Ignore = in all classes
- %ignore operator=; // Ignore = everywhere.
- %rename(__sub__) Complex::operator-;
- %rename(__neg__) Complex::operator-(); // Unary -
- </pre>
- </div>
- <p>
- The last part of this example illustrates how multiple definitions of
- the <tt>operator-</tt> method might be handled.
- </p>
- <p>
- Handling operators in this manner is mostly straightforward. However, there are a few subtle
- issues to keep in mind:
- </p>
- <ul>
- <li><p>In C++, it is fairly common to define different versions of the operators to account for
- different types. For example, a class might also include a friend function like this:</p>
- <div class="code">
- <pre>
- class Complex {
- public:
- friend Complex operator+(Complex &, double);
- };
- Complex operator+(Complex &, double);
- </pre>
- </div>
- <p>
- SWIG simply ignores all <tt>friend</tt> declarations. Furthermore, it
- doesn't know how to associate the associated <tt>operator+</tt> with
- the class (because it's not a member of the class).
- </p>
- <p>
- It's still possible to make a wrapper for this operator, but you'll
- have to handle it like a normal function. For example:
- </p>
- <div class="code">
- <pre>
- %rename(add_complex_double) operator+(Complex &, double);
- </pre>
- </div>
- </li>
- <li><p>Certain operators are ignored by default. For instance, <tt>new</tt> and <tt>delete</tt> operators
- are ignored as well as conversion operators.
- </p></li>
- <li>The semantics of certain C++ operators may not match those in the target language.
- </li>
- </ul>
- <H2><a name="SWIGPlus_class_extension"></a>6.17 Class extension</H2>
- <p>
- New methods can be added to a class using the <tt>%extend</tt>
- directive. This directive is primarily used in conjunction with proxy
- classes to add additional functionality to an existing class. For
- example :
- </p>
- <div class="code"><pre>
- %module vector
- %{
- #include "vector.h"
- %}
- class Vector {
- public:
- double x,y,z;
- Vector();
- ~Vector();
- ... bunch of C++ methods ...
- %extend {
- char *__str__() {
- static char temp[256];
- sprintf(temp,"[ %g, %g, %g ]", $self->x,$self->y,$self->z);
- return &temp[0];
- }
- }
- };
- </pre></div>
- <p>
- This code adds a<tt> __str__</tt> method to our class for producing a
- string representation of the object. In Python, such a method would
- allow us to print the value of an object using the <tt>print</tt>
- command.
- </p>
- <div class="targetlang"><pre>
- >>>
- >>> v = Vector();
- >>> v.x = 3
- >>> v.y = 4
- >>> v.z = 0
- >>> print(v)
- [ 3.0, 4.0, 0.0 ]
- >>>
- </pre></div>
- <p>
- The C++ 'this' pointer is often needed to access member variables, methods etc.
- The <tt>$self</tt> special variable should be used wherever you could use 'this'.
- The example above demonstrates this for accessing member variables.
- Note that the members dereferenced by <tt>$self</tt> must be public members as the code is ultimately generated
- into a global function and so will not have any access to non-public members.
- The implicit 'this' pointer that is present in C++ methods is not present in <tt>%extend</tt> methods.
- In order to access anything in the extended class or its base class, an explicit 'this' is required.
- The following example shows how one could access base class members:
- </p>
- <div class="code"><pre>
- struct Base {
- virtual void method(int v) {
- ...
- }
- int value;
- };
- struct Derived : Base {
- };
- %extend Derived {
- virtual void method(int v) {
- $self->Base::method(v); // akin to this->Base::method(v);
- $self->value = v; // akin to this->value = v;
- ...
- }
- }
- </pre></div>
- <p>
- The<tt> %extend</tt> directive follows all of the same conventions
- as its use with C structures. Please refer to the <a href="SWIG.html#SWIG_adding_member_functions">Adding member functions to C structures</a>
- section for further details.
- </p>
- <p>
- <b>Compatibility note:</b> The <tt>%extend</tt> directive is a new
- name for the <tt>%addmethods</tt> directive in SWIG1.1. Since <tt>%addmethods</tt> could
- be used to extend a structure with more than just methods, a more suitable
- directive name has been chosen.
- </p>
- <H2><a name="SWIGPlus_nn30"></a>6.18 Templates</H2>
- <p>
- Template type names may appear anywhere a type
- is expected in an interface file. For example:
- </p>
- <div class="code">
- <pre>
- void foo(vector<int> *a, int n);
- void bar(list<int,100> *x);
- </pre>
- </div>
- <p>
- There are some restrictions on the use of non-type arguments. Simple literals
- are supported, and so are some constant expressions. However, use of '<'
- and '>' within a constant expressions currently is not supported by SWIG
- ('<=' and '>=' are though). For example:
- </p>
- <div class="code">
- <pre>
- void bar(list<int,100> *x); // OK
- void bar(list<int,2*50> *x); // OK
- void bar(list<int,(2>1 ? 100 : 50)> *x) // Not supported
- </pre>
- </div>
- <p>
- The type system is smart enough to figure out clever games
- you might try to play with <tt>typedef</tt>. For instance, consider this code:
- </p>
- <div class="code">
- <pre>
- typedef int Integer;
- void foo(vector<int> *x, vector<Integer> *y);
- </pre>
- </div>
- <p>
- In this case, <tt>vector<Integer></tt> is exactly the same type
- as <tt>vector<int></tt>. The wrapper for <tt>foo()</tt> will
- accept either variant.
- </p>
- <p>
- Starting with SWIG-1.3.7, simple C++ template declarations can also be
- wrapped. SWIG-1.3.12 greatly expands upon the earlier implementation. Before discussing this any further, there are a few things
- you need to know about template wrapping. First, a bare C++ template
- does not define any sort of runnable object-code for which SWIG can
- normally create a wrapper. Therefore, in order to wrap a template,
- you need to give SWIG information about a particular template
- instantiation (e.g., <tt>vector<int></tt>,
- <tt>array<double></tt>, etc.). Second, an instantiation name
- such as <tt>vector<int></tt> is generally not a valid identifier
- name in most target languages. Thus, you will need to give the
- template instantiation a more suitable name such as <tt>intvector</tt>
- when creating a wrapper.
- </p>
- <p>
- To illustrate, consider the following template definition:
- </p>
- <div class="code"><pre>
- template<class T> class List {
- private:
- T *data;
- int nitems;
- int maxitems;
- public:
- List(int max) {
- data = new T [max];
- nitems = 0;
- maxitems = max;
- }
- ~List() {
- delete [] data;
- };
- void append(T obj) {
- if (nitems < maxitems) {
- data[nitems++] = obj;
- }
- }
- int length() {
- return nitems;
- }
- T get(int n) {
- return data[n];
- }
- };
- </pre></div>
- <p>
- By itself, this template declaration is useless--SWIG simply ignores it
- because it doesn't know how to generate any code until unless a definition of
- <tt>T</tt> is provided.
- </p>
- <p>
- One way to create wrappers for a specific template instantiation is to simply
- provide an expanded version of the class directly like this:
- </p>
- <div class="code">
- <pre>
- %rename(intList) List<int>; // Rename to a suitable identifier
- class List<int> {
- private:
- int *data;
- int nitems;
- int maxitems;
- public:
- List(int max);
- ~List();
- void append(int obj);
- int length();
- int get(int n);
- };
- </pre>
- </div>
- <p>
- The <tt>%rename</tt> directive is needed to give the template class an appropriate identifier
- name in the target language (most languages would not recognize C++ template syntax as a valid
- class name). The rest of the code is the same as what would appear in a normal
- class definition.
- </p>
- <p>
- Since manual expansion of templates gets old in a hurry, the <tt>%template</tt> directive can
- be used to create instantiations of a template class. Semantically, <tt>%template</tt> is
- simply a shortcut---it expands template code in exactly the same way as shown above. Here
- are some examples:
- </p>
- <div class="code">
- <pre>
- /* Instantiate a few different versions of the template */
- %template(intList) List<int>;
- %template(doubleList) List<double>;
- </pre>
- </div>
- <p>
- The argument to <tt>%template()</tt> is the name of the instantiation
- in the target language. The name you choose should not conflict with
- any other declarations in the interface file with one exception---it
- is okay for the template name to match that of a typedef declaration.
- For example:
- </p>
- <div class="code">
- <pre>
- %template(intList) List<int>;
- ...
- typedef List<int> intList; // OK
- </pre>
- </div>
- <p>
- SWIG can also generate wrappers for function templates using a similar technique.
- For example:
- </p>
- <div class="code">
- <pre>
- // Function template
- template<class T> T max(T a, T b) { return a > b ? a : b; }
- // Make some different versions of this function
- %template(maxint) max<int>;
- %template(maxdouble) max<double>;
- </pre>
- </div>
- <p>
- In this case, <tt>maxint</tt> and <tt>maxdouble</tt> become unique names for specific
- instantiations of the function.
- </p>
- <p>
- The number of arguments supplied to <tt>%template</tt> should match that in the
- original template definition. Template default arguments are supported. For example:
- </p>
- <div class="code">
- <pre>
- template vector<typename T, int max=100> class vector {
- ...
- };
- %template(intvec) vector<int>; // OK
- %template(vec1000) vector<int,1000>; // OK
- </pre>
- </div>
- <p>
- The <tt>%template</tt> directive should not be used to wrap the same
- template instantiation more than once in the same scope. This will
- generate an error. For example:
- </p>
- <div class="code">
- <pre>
- %template(intList) List<int>;
- %template(Listint) List<int>; // Error. Template already wrapped.
- </pre>
- </div>
- <p>
- This error is caused because the template expansion results in two
- identical classes with the same name. This generates a symbol table
- conflict. Besides, it probably more efficient to only wrap a specific
- instantiation only once in order to reduce the potential for code
- bloat.
- </p>
- <p>
- Since the type system knows how to handle <tt>typedef</tt>, it is
- generally not necessary to instantiate different versions of a template
- for typenames that are equivalent. For instance, consider this code:
- </p>
- <div class="code">
- <pre>
- %template(intList) vector<int>;
- typedef int Integer;
- ...
- void foo(vector<Integer> *x);
- </pre>
- </div>
- <p>
- In this case, <tt>vector<Integer></tt> is exactly the same type as
- <tt>vector<int></tt>. Any use of <tt>Vector<Integer></tt> is mapped back to the
- instantiation of <tt>vector<int></tt> created earlier. Therefore, it is
- not necessary to instantiate a new class for the type <tt>Integer</tt> (doing so is
- redundant and will simply result in code bloat).
- </p>
- <p>
- When a template is instantiated using <tt>%template</tt>, information
- about that class is saved by SWIG and used elsewhere in the program.
- For example, if you wrote code like this,
- </p>
- <div class="code">
- <pre>
- ...
- %template(intList) List<int>;
- ...
- class UltraList : public List<int> {
- ...
- };
- </pre>
- </div>
- <p>
- then SWIG knows that <tt>List<int></tt> was already wrapped as a class called
- <tt>intList</tt> and arranges to handle the inheritance correctly. If, on the other hand,
- nothing is known about <tt>List<int></tt>, you will get a warning message similar to this:
- </p>
- <div class="shell">
- <pre>
- example.h:42. Nothing known about class 'List<int >' (ignored).
- example.h:42. Maybe you forgot to instantiate 'List<int >' using %template.
- </pre>
- </div>
- <p>
- If a template class inherits from another template class, you need to
- make sure that base classes are instantiated before derived classes.
- For example:
- </p>
- <div class="code">
- <pre>
- template<class T> class Foo {
- ...
- };
- template<class T> class Bar : public Foo<T> {
- ...
- };
- // Instantiate base classes first
- %template(intFoo) Foo<int>;
- %template(doubleFoo) Foo<double>;
- // Now instantiate derived classes
- %template(intBar) Bar<int>;
- %template(doubleBar) Bar<double>;
- </pre>
- </div>
- <p>
- The order is important since SWIG uses the instantiation names to
- properly set up the inheritance hierarchy in the resulting wrapper
- code (and base classes need to be wrapped before derived classes).
- Don't worry--if you get the order wrong, SWIG should generate a warning message.
- </p>
- <p>
- Occasionally, you may need to tell SWIG about base classes that are defined by templates,
- but which aren't supposed to be wrapped. Since SWIG is not able to automatically
- instantiate templates for this purpose, you must do it manually. To do this, simply
- use <tt>%template</tt> with no name. For example:
- </p>
- <div class="code">
- <pre>
- // Instantiate traits<double,double>, but don't wrap it.
- %template() traits<double,double>;
- </pre>
- </div>
- <p>
- If you have to instantiate a lot of different classes for many different types,
- you might consider writing a SWIG macro. For example:
- </p>
- <div class="code">
- <pre>
- %define TEMPLATE_WRAP(prefix, T...)
- %template(prefix ## Foo) Foo<T >;
- %template(prefix ## Bar) Bar<T >;
- ...
- %enddef
- TEMPLATE_WRAP(int, int)
- TEMPLATE_WRAP(double, double)
- TEMPLATE_WRAP(String, char *)
- TEMPLATE_WRAP(PairStringInt, std::pair<string, int>)
- ...
- </pre>
- </div>
- <p>
- Note the use of a vararg macro for the type T. If this wasn't used, the comma in the templated type in the last example would not be possible.
- </p>
- <p>
- The SWIG template mechanism <em>does</em> support specialization. For instance, if you define
- a class like this,
- </p>
- <div class="code">
- <pre>
- template<> class List<int> {
- private:
- int *data;
- int nitems;
- int maxitems;
- public:
- List(int max);
- ~List();
- void append(int obj);
- int length();
- int get(int n);
- };
- </pre>
- </div>
- <p>
- then SWIG will use this code whenever the user expands <tt>List<int></tt>. In practice,
- this may have very little effect on the underlying wrapper code since
- specialization is often used to provide slightly modified method bodies (which
- are ignored by SWIG). However, special SWIG
- directives such as <tt>%typemap</tt>, <tt>%extend</tt>, and so forth can be attached
- to a specialization to provide customization for specific types.
- </p>
- <p>
- Partial template specialization is partially supported by SWIG. For example, this
- code defines a template that is applied when the template argument is a pointer.
- </p>
- <div class="code">
- <pre>
- template<class T> class List<T*> {
- private:
- T *data;
- int nitems;
- int maxitems;
- public:
- List(int max);
- ~List();
- void append(int obj);
- int length();
- T get(int n);
- };
- </pre>
- </div>
- <p>
- SWIG supports both template explicit specialization and partial specialization. Consider:
- </p>
- <div class="code">
- <pre>
- template<class T1, class T2> class Foo { }; // (1) primary template
- template<> class Foo<double *, int *> { }; // (2) explicit specialization
- template<class T1, class T2> class Foo<T1, T2 *> { }; // (3) partial specialization
- </pre>
- </div>
- <p>
- SWIG is able to properly match explicit instantiations:
- </p>
- <div class="code">
- <pre>
- <tt>Foo<double *, int *></tt> // explicit specialization matching (2)
- </pre>
- </div>
- <p>
- SWIG implements template argument deduction so that the following partial specialization examples work just like they would with a C++ compiler:
- </p>
- <div class="code">
- <pre>
- <tt>Foo<int *, int *></tt> // partial specialization matching (3)
- <tt>Foo<int *, const int *></tt> // partial specialization matching (3)
- <tt>Foo<int *, int **></tt> // partial specialization matching (3)
- </pre>
- </div>
- <p>
- Member function templates are supported. The underlying principle is the same
- as for normal templates--SWIG can't create a wrapper unless you provide
- more information about types. For example, a class with a member template might
- look like this:
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- template<class T> void bar(T x, T y) { ... };
- ...
- };
- </pre>
- </div>
- <p>
- To expand the template, simply use <tt>%template</tt> inside the class.
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- template<class T> void bar(T x, T y) { ... };
- ...
- %template(barint) bar<int>;
- %template(bardouble) bar<double>;
- };
- </pre>
- </div>
- <p>
- Or, if you want to leave the original class definition alone, just do this:
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- template<class T> void bar(T x, T y) { ... };
- ...
- };
- ...
- %extend Foo {
- %template(barint) bar<int>;
- %template(bardouble) bar<double>;
- };
- </pre>
- </div>
- <p>
- or simply
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- template<class T> void bar(T x, T y) { ... };
- ...
- };
- ...
- %template(bari) Foo::bar<int>;
- %template(bard) Foo::bar<double>;
- </pre>
- </div>
- <p>
- In this case, the <tt>%extend</tt> directive is not needed, and
- <tt>%template</tt> does the exactly same job, i.e., it adds two new
- methods to the Foo class.
- </p>
- <p>
- Note: because of the way that templates are handled, the <tt>%template</tt> directive
- must always appear <em>after</em> the definition of the template to be expanded.
- </p>
- <p>
- Now, if your target language supports overloading, you can even try
- </p>
- <div class="code">
- <pre>
- %template(bar) Foo::bar<int>;
- %template(bar) Foo::bar<double>;
- </pre>
- </div>
- <p>
- and since the two new wrapped methods have the same name 'bar', they will be
- overloaded, and when called, the correct method will be dispatched
- depending on the argument type.
- </p>
- <p>
- When used with members, the <tt>%template</tt> directive may be placed in another
- template class. Here is a slightly perverse example:
- </p>
- <div class="code">
- <pre>
- // A template
- template<class T> class Foo {
- public:
- // A member template
- template<class S> T bar(S x, S y) { ... };
- ...
- };
- // Expand a few member templates
- %extend Foo {
- %template(bari) bar<int>;
- %template(bard) bar<double>;
- }
- // Create some wrappers for the template
- %template(Fooi) Foo<int>;
- %template(Food) Foo<double>;
- </pre>
- </div>
- <p>
- Miraculously, you will find that each expansion of <tt>Foo</tt> has member
- functions <tt>bari()</tt> and <tt>bard()</tt> added.
- </p>
- <p>
- A common use of member templates is to define constructors for copies
- and conversions. For example:
- </p>
- <div class="code">
- <pre>
- template<class T1, class T2> struct pair {
- T1 first;
- T2 second;
- pair() : first(T1()), second(T2()) { }
- pair(const T1 &x, const T2 &y) : first(x), second(y) { }
- template<class U1, class U2> pair(const pair<U1,U2> &x)
- : first(x.first),second(x.second) { }
- };
- </pre>
- </div>
- <p>
- This declaration is perfectly acceptable to SWIG, but the constructor template will be ignored
- unless you explicitly expand it. To do that, you could expand a few versions of the constructor
- in the template class itself. For example:
- </p>
- <div class="code">
- <pre>
- %extend pair {
- %template(pair) pair<T1,T2>; // Generate default copy constructor
- };
- </pre>
- </div>
- <p>
- When using <tt>%extend</tt> in this manner, notice how you can still use the template parameters in
- the original template definition.
- </p>
- <p>
- Alternatively, you could expand the constructor template in selected instantiations. For example:
- </p>
- <div class="code">
- <pre>
- // Instantiate a few versions
- %template(pairii) pair<int,int>;
- %template(pairdd) pair<double,double>;
- // Create a default constructor only
- %extend pair<int,int> {
- %template(paird) pair<int,int>; // Default constructor
- };
- // Create default and conversion constructors
- %extend pair<double,double> {
- %template(paird) pair<double,dobule>; // Default constructor
- %template(pairc) pair<int,int>; // Conversion constructor
- };
- </pre>
- </div>
- <p>And if your target language supports overloading, then you can try
- instead:
- </p>
- <div class="code">
- <pre>
- // Create default and conversion constructors
- %extend pair<double,double> {
- %template(pair) pair<double,dobule>; // Default constructor
- %template(pair) pair<int,int>; // Conversion constructor
- };
- </pre>
- </div>
- <p>
- In this case, the default and conversion constructors have the same
- name. Hence, SWIG will overload them and define an unique visible
- constructor, that will dispatch the proper call depending on the argument
- type.
- </p>
- <p>
- If all of this isn't quite enough and you really want to make
- someone's head explode, SWIG directives such as
- <tt>%rename</tt>, <tt>%extend</tt>, and <tt>%typemap</tt> can be
- included directly in template definitions. For example:
- </p>
- <div class="code"><pre>
- // File : list.h
- template<class T> class List {
- ...
- public:
- %rename(__getitem__) get(int);
- List(int max);
- ~List();
- ...
- T get(int index);
- %extend {
- char *__str__() {
- /* Make a string representation */
- ...
- }
- }
- };
- </pre></div>
- <p>
- In this example, the extra SWIG directives are propagated to <em>every</em> template
- instantiation.
- </p>
- <p>
- It is also possible to separate these declarations from the template class. For example:
- </p>
- <div class="code">
- <pre>
- %rename(__getitem__) List::get;
- %extend List {
- char *__str__() {
- /* Make a string representation */
- ...
- }
- /* Make a copy */
- T *__copy__() {
- return new List<T>(*$self);
- }
- };
- ...
- template<class T> class List {
- ...
- public:
- List() { };
- T get(int index);
- ...
- };
- </pre>
- </div>
- <p>
- When <tt>%extend</tt> is decoupled from the class definition, it is
- legal to use the same template parameters as provided in the class definition.
- These are replaced when the template is expanded.
- In addition, the <tt>%extend</tt> directive can be used to add
- additional methods to a specific instantiation. For example:
- </p>
- <div class="code">
- <pre>
- %template(intList) List<int>;
- %extend List<int> {
- void blah() {
- printf("Hey, I'm an List<int>!\n");
- }
- };
- </pre>
- </div>
- <p>
- SWIG even supports overloaded templated functions. As usual the <tt>%template</tt> directive
- is used to wrap templated functions. For example:
- </p>
- <div class="code">
- <pre>
- template<class T> void foo(T x) { };
- template<class T> void foo(T x, T y) { };
- %template(foo) foo<int>;
- </pre>
- </div>
- <p>
- This will generate two overloaded wrapper methods, the first will take a single integer as an argument
- and the second will take two integer arguments.
- </p>
- <p>
- Needless to say, SWIG's template support provides plenty of
- opportunities to break the universe. That said, an important final
- point is that <b>SWIG does not perform extensive error checking of
- templates!</b> Specifically, SWIG does not perform type checking nor
- does it check to see if the actual contents of the template
- declaration make any sense. Since the C++ compiler will hopefully
- check this when it compiles the resulting wrapper file, there is no
- practical reason for SWIG to duplicate this functionality (besides,
- none of the SWIG developers are masochistic enough to want to
- implement this right now).
- </p>
- <p>
- <b>Compatibility Note</b>: The first implementation of template support relied heavily on
- macro expansion in the preprocessor. Templates have been more tightly integrated into
- the parser and type system in SWIG-1.3.12 and the preprocessor is no longer used. Code
- that relied on preprocessing features in template expansion will no longer work. However,
- SWIG still allows the # operator to be used to generate a string from a template argument.
- </p>
- <p>
- <b>Compatibility Note</b>: In earlier versions of SWIG, the <tt>%template</tt> directive
- introduced a new class name. This name could then be used with other directives. For example:
- </p>
- <div class="code">
- <pre>
- %template(vectori) vector<int>;
- %extend vectori {
- void somemethod() { }
- };
- </pre>
- </div>
- <p>
- This behavior is no longer supported. Instead, you should use the original template name
- as the class name. For example:
- </p>
- <div class="code">
- <pre>
- %template(vectori) vector<int>;
- %extend vector<int> {
- void somemethod() { }
- };
- </pre>
- </div>
- <p>
- Similar changes apply to typemaps and other customization features.
- </p>
- <H2><a name="SWIGPlus_nn31"></a>6.19 Namespaces</H2>
- <p>
- Support for C++ namespaces is a relatively late addition to SWIG,
- first appearing in SWIG-1.3.12. Before describing the implementation,
- it is worth noting that the semantics of C++ namespaces is extremely
- non-trivial--especially with regard to the C++ type system and class
- machinery. At a most basic level, namespaces are sometimes used to
- encapsulate common functionality. For example:
- </p>
- <div class="code">
- <pre>
- namespace math {
- double sin(double);
- double cos(double);
- class Complex {
- double im,re;
- public:
- ...
- };
- ...
- };
- </pre>
- </div>
- <p>
- Members of the namespace are accessed in C++ by prepending the namespace prefix
- to names. For example:
- </p>
- <div class="code">
- <pre>
- double x = math::sin(1.0);
- double magnitude(math::Complex *c);
- math::Complex c;
- ...
- </pre>
- </div>
- <p>
- At this level, namespaces are relatively easy to manage. However, things start to get
- very ugly when you throw in the other ways a namespace can be used. For example,
- selective symbols can be exported from a namespace with <tt>using</tt>.
- </p>
- <div class="code">
- <pre>
- using math::Complex;
- double magnitude(Complex *c); // Namespace prefix stripped
- </pre>
- </div>
- <p>
- Similarly, the contents of an entire namespace can be made available like this:
- </p>
- <div class="code">
- <pre>
- using namespace math;
- double x = sin(1.0);
- double magnitude(Complex *c);
- </pre>
- </div>
- <p>
- Alternatively, a namespace can be aliased:
- </p>
- <div class="code">
- <pre>
- namespace M = math;
- double x = M::sin(1.0);
- double magnitude(M::Complex *c);
- </pre>
- </div>
- <p>
- Using combinations of these features, it is possible to write head-exploding code like this:
- </p>
- <div class="code">
- <pre>
- namespace A {
- class Foo {
- };
- }
- namespace B {
- namespace C {
- using namespace A;
- }
- typedef C::Foo FooClass;
- }
- namespace BIGB = B;
- namespace D {
- using BIGB::FooClass;
- class Bar : public FooClass {
- }
- };
- class Spam : public D::Bar {
- };
- void evil(A::Foo *a, B::FooClass *b, B::C::Foo *c, BIGB::FooClass *d,
- BIGB::C::Foo *e, D::FooClass *f);
- </pre>
- </div>
- <p>
- Given the possibility for such perversion, it's hard to imagine how
- every C++ programmer might want such code wrapped into the target
- language. Clearly this code defines three different classes. However, one
- of those classes is accessible under at least six different names!
- </p>
- <p>
- SWIG fully supports C++ namespaces in its internal type system and
- class handling code. If you feed SWIG the above code, it will be
- parsed correctly, it will generate compilable wrapper code, and it
- will produce a working scripting language module. However, the
- default wrapping behavior is to flatten namespaces in the target
- language. This means that the contents of all namespaces are merged
- together in the resulting scripting language module. For example, if
- you have code like this,
- </p>
- <div class="code">
- <pre>
- %module foo
- namespace foo {
- void bar(int);
- void spam();
- }
- namespace bar {
- void blah();
- }
- </pre>
- </div>
- <p>
- then SWIG simply creates three wrapper functions <tt>bar()</tt>,
- <tt>spam()</tt>, and <tt>blah()</tt> in the target language. SWIG
- does not prepend the names with a namespace prefix nor are the
- functions packaged in any kind of nested scope.
- </p>
- <p>
- There is some rationale for taking this approach. Since C++
- namespaces are often used to define modules in C++, there is a natural
- correlation between the likely contents of a SWIG module and the contents of
- a namespace. For instance, it would not be unreasonable to assume
- that a programmer might make a separate extension module for each C++
- namespace. In this case, it would be redundant to prepend everything
- with an additional namespace prefix when the module itself already
- serves as a namespace in the target language. Or put another way, if
- you want SWIG to keep namespaces separate, simply wrap each namespace with its
- own SWIG interface.
- </p>
- <p>
- Because namespaces are flattened, it is possible for symbols defined in different
- namespaces to generate a name conflict in the target language. For example:
- </p>
- <div class="code">
- <pre>
- namespace A {
- void foo(int);
- }
- namespace B {
- void foo(double);
- }
- </pre>
- </div>
- <p>
- When this conflict occurs, you will get an error message that resembles this:
- </p>
- <div class="shell">
- <pre>
- example.i:26. Error. 'foo' is multiply defined in the generated module.
- example.i:23. Previous declaration of 'foo'
- </pre>
- </div>
- <p>
- To resolve this error, simply use <tt>%rename</tt> to disambiguate the declarations. For example:
- </p>
- <div class="code">
- <pre>
- %rename(B_foo) B::foo;
- ...
- namespace A {
- void foo(int);
- }
- namespace B {
- void foo(double); // Gets renamed to B_foo
- }
- </pre>
- </div>
- <p>
- Similarly, <tt>%ignore</tt> can be used to ignore declarations.
- </p>
- <p>
- <tt>using</tt> declarations do not have any effect on the generated wrapper
- code. They are ignored by SWIG language modules and they do not result in any
- code. However, these declarations <em>are</em> used by the internal type
- system to track type-names. Therefore, if you have code like this:
- </p>
- <div class="code">
- <pre>
- namespace A {
- typedef int Integer;
- }
- using namespace A;
- void foo(Integer x);
- </pre>
- </div>
- <p>
- SWIG knows that <tt>Integer</tt> is the same as <tt>A::Integer</tt> which
- is the same as <tt>int</tt>.
- </p>
- <P>
- Namespaces may be combined with templates. If necessary, the
- <tt>%template</tt> directive can be used to expand a template defined
- in a different namespace. For example:
- </p>
- <div class="code">
- <pre>
- namespace foo {
- template<typename T> T max(T a, T b) { return a > b ? a : b; }
- }
- using foo::max;
- %template(maxint) max<int>; // Okay.
- %template(maxfloat) foo::max<float>; // Okay (qualified name).
- namespace bar {
- using namespace foo;
- %template(maxdouble) max<double>; // Okay.
- }
- </pre>
- </div>
- <p>
- The combination of namespaces and other SWIG directives may introduce subtle scope-related problems.
- The key thing to keep in mind is that all SWIG generated wrappers are produced
- in the <em>global</em> namespace. Symbols from other namespaces are always accessed using fully
- qualified names---names are never imported into the global space unless the interface happens to
- do so with a <tt>using</tt> declaration. In almost all cases, SWIG adjusts typenames and symbols
- to be fully qualified. However, this is not done in code fragments such as function bodies,
- typemaps, exception handlers, and so forth. For example, consider the following:
- </p>
- <div class="code">
- <pre>
- namespace foo {
- typedef int Integer;
- class bar {
- public:
- ...
- };
- }
- %extend foo::bar {
- Integer add(Integer x, Integer y) {
- Integer r = x + y; // Error. Integer not defined in this scope
- return r;
- }
- };
- </pre>
- </div>
- <p>
- In this case, SWIG correctly resolves the added method parameters and return type to
- <tt>foo::Integer</tt>. However, since function bodies aren't parsed and such code is
- emitted in the global namespace, this code produces a compiler error about <tt>Integer</tt>.
- To fix the problem, make sure you use fully qualified names. For example:
- </p>
- <div class="code">
- <pre>
- %extend foo::bar {
- Integer add(Integer x, Integer y) {
- foo::Integer r = x + y; // Ok.
- return r;
- }
- };
- </pre>
- </div>
- <p>
- <b>Note:</b> SWIG does <em>not</em> propagate <tt>using</tt> declarations to
- the resulting wrapper code. If these declarations appear in an interface,
- they should <em>also</em> appear in any header files that might have been
- included in a <tt>%{ ... %}</tt> section. In other words, don't insert extra
- <tt>using</tt> declarations into a SWIG interface unless they also appear
- in the underlying C++ code.
- </p>
- <p>
- <b>Note:</b> Code inclusion directives such as <tt>%{ ... %}</tt> or
- <tt>%inline %{ ... %}</tt> should not be placed inside a namespace declaration.
- The code emitted by these directives will not be enclosed in a namespace and
- you may get very strange results. If you need to use namespaces with
- these directives, consider the following:
- </p>
- <div class="code">
- <pre>
- // Good version
- %inline %{
- namespace foo {
- void bar(int) { ... }
- ...
- }
- %}
- // Bad version. Emitted code not placed in namespace.
- namespace foo {
- %inline %{
- void bar(int) { ... } /* I'm bad */
- ...
- %}
- }
- </pre>
- </div>
- <p>
- <b>Note:</b> When the <tt>%extend</tt> directive is used inside a namespace, the namespace name is
- included in the generated functions. For example, if you have code like this,
- </p>
- <div class="code">
- <pre>
- namespace foo {
- class bar {
- public:
- %extend {
- int blah(int x);
- };
- };
- }
- </pre>
- </div>
- <p>
- the added method <tt>blah()</tt> is mapped to a function <tt>int foo_bar_blah(foo::bar *self, int x)</tt>.
- This function resides in the global namespace.
- </p>
- <p>
- <b>Note:</b> Although namespaces are flattened in the target language, the SWIG generated wrapper
- code observes the same namespace conventions as used in the input file. Thus, if there are no symbol
- conflicts in the input, there will be no conflicts in the generated code.
- </p>
- <p>
- <b>Note:</b> In the same way that no resolution is performed on parameters, a conversion operator name must match exactly to how it is defined. Do not change the qualification of the operator. For example, suppose you had an interface like this:
- </p>
- <div class="code">
- <pre>
- namespace foo {
- class bar;
- class spam {
- public:
- ...
- operator bar(); // Conversion of spam -> bar
- ...
- };
- }
- </pre>
- </div>
- <p>
- The following is how the feature is expected to be written for a successful match:
- </p>
- <div class="code">
- <pre>
- %rename(tofoo) foo::spam::operator bar();
- </pre>
- </div>
- <p>
- The following does not work as no namespace resolution is performed in the matching of conversion operator names:
- </p>
- <div class="code">
- <pre>
- %rename(tofoo) foo::spam::operator <b>foo::</b>bar();
- </pre>
- </div>
- <p>
- Note, however, that if the operator is defined using a qualifier in its name, then the feature must use it too...
- </p>
- <div class="code">
- <pre>
- %rename(tofoo) foo::spam::operator bar(); // will not match
- %rename(tofoo) foo::spam::operator foo::bar(); // will match
- namespace foo {
- class bar;
- class spam {
- public:
- ...
- operator foo::bar();
- ...
- };
- }
- </pre>
- </div>
- <p>
- <b>Compatibility Note:</b> Versions of SWIG prior to 1.3.32 were inconsistent in this approach. A fully qualified name was usually required, but would not work in some situations.
- </p>
- <p>
- <b>Note:</b> The flattening of namespaces is only intended to serve as
- a basic namespace implementation.
- None of the target language modules are currently programmed
- with any namespace awareness. In the future, language modules may or may not provide
- more advanced namespace support.
- </p>
- <H2><a name="SWIGPlus_renaming_templated_types_namespaces"></a>6.20 Renaming templated types in namespaces</H2>
- <p>
- As has been mentioned, when %rename includes parameters, the parameter types must match exactly (no typedef or namespace resolution is performed).
- SWIG treats templated types slightly differently and has an additional matching rule so unlike non-templated types, an exact match is not always required.
- If the fully qualified templated type is specified, it will have a higher precedence over the generic template type.
- In the example below, the generic template type is used to rename to <tt>bbb</tt> and the fully qualified type is used to rename to <tt>ccc</tt>.
- </p>
- <div class="code">
- <pre>
- %rename(bbb) Space::ABC::aaa(T t); // will match but with lower precedence than ccc
- %rename(ccc) Space::ABC<Space::XYZ>::aaa(Space::XYZ t); // will match but with higher precedence than bbb
- namespace Space {
- class XYZ {};
- template<typename T> struct ABC {
- void aaa(T t) {}
- };
- }
- %template(ABCXYZ) Space::ABC<Space::XYZ>;
- </pre>
- </div>
- <p>
- It should now be apparent that there are many ways to achieve a renaming with %rename. This is demonstrated
- by the following two examples, which are effectively the same as the above example.
- Below shows how %rename can be placed inside a namespace.
- </p>
- <div class="code">
- <pre>
- namespace Space {
- %rename(bbb) ABC::aaa(T t); // will match but with lower precedence than ccc
- %rename(ccc) ABC<Space::XYZ>::aaa(Space::XYZ t); // will match but with higher precedence than bbb
- %rename(ddd) ABC<Space::XYZ>::aaa(XYZ t); // will not match
- }
- namespace Space {
- class XYZ {};
- template<typename T> struct ABC {
- void aaa(T t) {}
- };
- }
- %template(ABCXYZ) Space::ABC<Space::XYZ>;
- </pre>
- </div>
- <p>
- Note that <tt>ddd</tt> does not match as there is no namespace resolution for parameter types and the fully qualified type must be specified for template type expansion.
- The following example shows how %rename can be placed within %extend.
- </p>
- <div class="code">
- <pre>
- namespace Space {
- %extend ABC {
- %rename(bbb) aaa(T t); // will match but with lower precedence than ccc
- }
- %extend ABC<Space::XYZ> {
- %rename(ccc) aaa(Space::XYZ t); // will match but with higher precedence than bbb
- %rename(ddd) aaa(XYZ t); // will not match
- }
- }
- namespace Space {
- class XYZ {};
- template<typename T> struct ABC {
- void aaa(T t) {}
- };
- }
- %template(ABCXYZ) Space::ABC<Space::XYZ>;
- </pre>
- </div>
- <H2><a name="SWIGPlus_exception_specifications"></a>6.21 Exception specifications</H2>
- <p>
- When C++ programs utilize exceptions, exceptional behavior is sometimes specified as
- part of a function or method declaration. For example:
- </p>
- <div class="code">
- <pre>
- class Error { };
- class Foo {
- public:
- ...
- void blah() throw(Error);
- ...
- };
- </pre>
- </div>
- <p>
- If an exception specification is used, SWIG automatically generates
- wrapper code for catching the indicated exception and, when possible,
- rethrowing it into the target language, or converting it into an error
- in the target language otherwise. For example, in Python, you can
- write code like this:
- </p>
- <div class="targetlang">
- <pre>
- f = Foo()
- try:
- f.blah()
- except Error,e:
- # e is a wrapped instance of "Error"
- </pre>
- </div>
- <p>
- Details of how to tailor code for handling the caught C++ exception and converting it into the target language's exception/error handling mechanism
- is outlined in the <a href="Typemaps.html#throws_typemap">"throws" typemap</a> section.
- </p>
- <p>
- Since exception specifications are sometimes only used sparingly, this alone may not be enough to
- properly handle C++ exceptions. To do that, a different set of special SWIG directives are used.
- Consult the "<a href="Customization.html#exception">Exception handling with %exception</a>" section for details.
- The next section details a way of simulating an exception specification or replacing an existing one.
- </p>
- <H2><a name="SWIGPlus_catches"></a>6.22 Exception handling with %catches</H2>
- <p>
- Exceptions are automatically handled for methods with an exception specification.
- Similar handling can be achieved for methods without exception specifications through the <tt>%catches</tt> feature.
- It is also possible to replace any declared exception specification using the <tt>%catches</tt> feature.
- In fact, <tt>%catches</tt> uses the same <a href="Typemaps.html#throws_typemap">"throws" typemaps</a> that SWIG uses for exception specifications in handling exceptions.
- The <tt>%catches</tt> feature must contain a list of possible types that can be thrown.
- For each type that is in the list, SWIG will generate a catch handler, in the same way that it would for types declared in the exception specification.
- Note that the list can also include the catch all specification "...".
- For example,
- </p>
- <div class="code">
- <pre>
- struct EBase { virtual ~EBase(); };
- struct Error1 : EBase { };
- struct Error2 : EBase { };
- struct Error3 : EBase { };
- struct Error4 : EBase { };
- %catches(Error1,Error2,...) Foo::bar();
- %catches(EBase) Foo::blah();
- class Foo {
- public:
- ...
- void bar();
- void blah() throw(Error1,Error2,Error3,Error4);
- ...
- };
- </pre>
- </div>
- <p>
- For the <tt>Foo::bar()</tt> method, which can throw anything,
- SWIG will generate catch handlers for <tt>Error1</tt>, <tt>Error2</tt> as well as a catch all handler (...).
- Each catch handler will convert the caught exception and convert it into a target language error/exception.
- The catch all handler will convert the caught exception into an unknown error/exception.
- </p>
- <p>
- Without the <tt>%catches</tt> feature being attached to <tt>Foo::blah()</tt>,
- SWIG will generate catch handlers for all of the types in the exception specification, that is, <tt>Error1, Error2, Error3, Error4</tt>.
- However, with the <tt>%catches</tt> feature above,
- just a single catch handler for the base class, <tt>EBase</tt> will be generated to convert the C++ exception into a target language error/exception.
- </p>
- <H2><a name="SWIGPlus_nn33"></a>6.23 Pointers to Members</H2>
- <p>
- Starting with SWIG-1.3.7, there is limited parsing support for pointers to C++ class members.
- For example:
- </p>
- <div class="code">
- <pre>
- double do_op(Object *o, double (Object::*callback)(double,double));
- extern double (Object::*fooptr)(double,double);
- %constant double (Object::*FOO)(double,double) = &Object::foo;
- </pre>
- </div>
- <p>
- Although these kinds of pointers can be parsed and represented by the
- SWIG type system, few language modules know how to handle them due to
- implementation differences from standard C pointers. Readers are
- <em>strongly</em> advised to consult an advanced text such as the "The
- Annotated C++ Manual" for specific details.
- </p>
- <p>
- When pointers to members are supported, the pointer value might appear as a special
- string like this:
- </p>
- <div class="targetlang">
- <pre>
- >>> print example.FOO
- _ff0d54a800000000_m_Object__f_double_double__double
- >>>
- </pre>
- </div>
- <p>
- In this case, the hexadecimal digits represent the entire value of the
- pointer which is usually the contents of a small C++ structure on most
- machines.
- </p>
- <p>
- SWIG's type-checking mechanism is also more limited when working with
- member pointers. Normally SWIG tries to keep track of inheritance
- when checking types. However, no such support is currently provided
- for member pointers.
- </p>
- <H2><a name="SWIGPlus_nn34"></a>6.24 Smart pointers and operator->()</H2>
- <p>
- In some C++ programs, objects are often encapsulated by smart-pointers
- or proxy classes. This is sometimes done to implement automatic memory management (reference counting) or
- persistence. Typically a smart-pointer is defined by a template class where
- the <tt>-></tt> operator has been overloaded. This class is then wrapped
- around some other class. For example:
- </p>
- <div class="code">
- <pre>
- // Smart-pointer class
- template<class T> class SmartPtr {
- T *pointee;
- public:
- ...
- T *operator->() {
- return pointee;
- }
- ...
- };
- // Ordinary class
- class Foo_Impl {
- public:
- int x;
- virtual void bar();
- ...
- };
- // Smart-pointer wrapper
- typedef SmartPtr<Foo_Impl> Foo;
- // Create smart pointer Foo
- Foo make_Foo() {
- return SmartPtr(new Foo_Impl());
- }
- // Do something with smart pointer Foo
- void do_something(Foo f) {
- printf("x = %d\n", f->x);
- f->bar();
- }
- </pre>
- </div>
- <p>
- A key feature of this approach is that by defining
- <tt>operator-></tt> the methods and attributes of the object
- wrapped by a smart pointer are transparently accessible. For example,
- expressions such as these (from the previous example),
- </p>
- <div class="code">
- <pre>
- f->x
- f->bar()
- </pre>
- </div>
- <p>
- are transparently mapped to the following
- </p>
- <div class="code">
- <pre>
- (f.operator->())->x;
- (f.operator->())->bar();
- </pre>
- </div>
- <p>
- When generating wrappers, SWIG tries to emulate this functionality to
- the extent that it is possible. To do this, whenever
- <tt>operator->()</tt> is encountered in a class, SWIG looks at its
- returned type and uses it to generate wrappers for accessing
- attributes of the underlying object. For example, wrapping the above
- code produces wrappers like this:
- </p>
- <div class="code">
- <pre>
- int Foo_x_get(Foo *f) {
- return (*f)->x;
- }
- void Foo_x_set(Foo *f, int value) {
- (*f)->x = value;
- }
- void Foo_bar(Foo *f) {
- (*f)->bar();
- }
- </pre>
- </div>
- <p>
- These wrappers take a smart-pointer instance as an argument, but
- dereference it in a way to gain access to the object returned by
- <tt>operator->()</tt>. You should carefully compare these wrappers
- to those in the first part of this chapter (they are slightly
- different).
- </p>
- <p>
- The end result is that access looks very similar to C++. For
- example, you could do this in Python:
- </p>
- <div class="targetlang">
- <pre>
- >>> f = make_Foo()
- >>> print f.x
- 0
- >>> f.bar()
- >>>
- </pre>
- </div>
- <p>
- When generating wrappers through a smart-pointer, SWIG tries to
- generate wrappers for all methods and attributes that might be
- accessible through <tt>operator->()</tt>. This includes any methods
- that might be accessible through inheritance. However, there are a number of restrictions:
- </p>
- <ul>
- <li>Member variables and methods are wrapped through a smart
- pointer. Enumerations, constructors, and destructors are not wrapped.
- </li>
- <li><p>If the smart-pointer class and the underlying object both define a method or
- variable of the same name, then the smart-pointer version has precedence. For
- example, if you have this code</p>
- <div class="code">
- <pre>
- class Foo {
- public:
- int x;
- };
- class Bar {
- public:
- int x;
- Foo *operator->();
- };
- </pre>
- </div>
- <p>
- then the wrapper for <tt>Bar::x</tt> accesses the <tt>x</tt> defined in <tt>Bar</tt>, and
- not the <tt>x</tt> defined in <tt>Foo</tt>.</p>
- </li>
- </ul>
- <p>
- If your intent is to only expose the smart-pointer class in the interface, it is not necessary to wrap both
- the smart-pointer class and the class for the underlying object. However, you must still tell SWIG about both
- classes if you want the technique described in this section to work. To only generate wrappers for the
- smart-pointer class, you can use the %ignore directive. For example:
- </p>
- <div class="code">
- <pre>
- %ignore Foo;
- class Foo { // Ignored
- };
- class Bar {
- public:
- Foo *operator->();
- ...
- };
- </pre>
- </div>
- <p>
- Alternatively, you can import the definition of <tt>Foo</tt> from a separate file using
- <tt>%import</tt>.
- </p>
-
- <p>
- <b>Note:</b> When a class defines <tt>operator->()</tt>, the operator itself is wrapped
- as a method <tt>__deref__()</tt>. For example:
- </p>
- <div class="targetlang">
- <pre>
- f = Foo() # Smart-pointer
- p = f.__deref__() # Raw pointer from operator->
- </pre>
- </div>
- <p>
- <b>Note:</b> To disable the smart-pointer behavior, use <tt>%ignore</tt> to ignore
- <tt>operator->()</tt>. For example:
- </p>
- <div class="code">
- <pre>
- %ignore Bar::operator->;
- </pre>
- </div>
- <p>
- <b>Note:</b> Smart pointer support was first added in SWIG-1.3.14.
- </p>
- <H2><a name="SWIGPlus_nn35"></a>6.25 Using declarations and inheritance</H2>
- <p>
- <tt>using</tt> declarations are sometimes used to adjust access to members of
- base classes. For example:
- </p>
- <div class="code">
- <pre>
- class Foo {
- public:
- int blah(int x);
- };
- class Bar {
- public:
- double blah(double x);
- };
- class FooBar : public Foo, public Bar {
- public:
- using Foo::blah;
- using Bar::blah;
- char *blah(const char *x);
- };
- </pre>
- </div>
- <p>
- In this example, the <tt>using</tt> declarations make different
- versions of the overloaded <tt>blah()</tt> method accessible from the
- derived class. For example:
- </p>
- <div class="code">
- <pre>
- FooBar *f;
- f->blah(3); // Ok. Invokes Foo::blah(int)
- f->blah(3.5); // Ok. Invokes Bar::blah(double)
- f->blah("hello"); // Ok. Invokes FooBar::blah(const char *);
- </pre>
- </div>
- <p>
- SWIG emulates the same functionality when creating wrappers. For example, if
- you wrap this code in Python, the module works just like you would expect:
- </p>
- <div class="targetlang">
- <pre>
- >>> import example
- >>> f = example.FooBar()
- >>> f.blah(3)
- >>> f.blah(3.5)
- >>> f.blah("hello")
- </pre>
- </div>
- <p>
- <tt>using</tt> declarations can also be used to change access when applicable. For example:
- </p>
- <div class="code">
- <pre>
- class Foo {
- protected:
- int x;
- int blah(int x);
- };
- class Bar : public Foo {
- public:
- using Foo::x; // Make x public
- using Foo::blah; // Make blah public
- };
- </pre>
- </div>
- <p>
- This also works in SWIG---the exposed declarations will be wrapped normally.
- </p>
- <p>
- When <tt>using</tt> declarations are used as shown in these examples, declarations
- from the base classes are copied into the derived class and wrapped normally. When
- copied, the declarations retain any properties that might have been attached using
- <tt>%rename</tt>, <tt>%ignore</tt>, or <tt>%feature</tt>. Thus, if a method is
- ignored in a base class, it will also be ignored by a <tt>using</tt> declaration.
- </p>
- <p>
- Because a <tt>using</tt> declaration does not provide fine-grained
- control over the declarations that get imported, it may be difficult
- to manage such declarations in applications that make heavy use of
- SWIG customization features. If you can't get <tt>using</tt> to work
- correctly, you can always change the interface to the following:
- </p>
- <div class="code">
- <pre>
- class FooBar : public Foo, public Bar {
- public:
- #ifndef SWIG
- using Foo::blah;
- using Bar::blah;
- #else
- int blah(int x); // explicitly tell SWIG about other declarations
- double blah(double x);
- #endif
- char *blah(const char *x);
- };
- </pre>
- </div>
- <p>
- <b>Notes:</b>
- </p>
- <ul>
- <li><p>If a derived class redefines a method defined in a base class, then a <tt>using</tt> declaration
- won't cause a conflict. For example:</p>
- <div class="code">
- <pre>
- class Foo {
- public:
- int blah(int );
- double blah(double);
- };
- class Bar : public Foo {
- public:
- using Foo::blah; // Only imports blah(double);
- int blah(int);
- };
- </pre>
- </div>
- <li><p>Resolving ambiguity in overloading may prevent declarations from being
- imported by <tt>using</tt>. For example:
- </p>
- <div class="code">
- <pre>
- %rename(blah_long) Foo::blah(long);
- class Foo {
- public:
- int blah(int);
- long blah(long); // Renamed to blah_long
- };
- class Bar : public Foo {
- public:
- using Foo::blah; // Only imports blah(int)
- double blah(double x);
- };
- </pre>
- </div>
- </ul>
- <H2><a name="SWIGPlus_nested_classes"></a>6.26 Nested classes</H2>
- <p>
- There is some support for nested structs and unions when wrapping C code,
- see <a href="SWIG.html#SWIG_nested_structs">Nested structures</a> for further details.
- The added complexity of C++ compared to C means this approach does not work well for
- C++ code (when using the -c++ command line option).
- For C++, a nested class is treated much like an opaque pointer, so anything useful within the nested class, such as its
- methods and variables, are not accessible from the target language.
- True nested class support may be added to SWIG in the future, however,
- until then some of the following workarounds can be applied to improve the situation.
- </p>
- <p>
- It might be possible to use partial class information as often you can accept that the nested class is not needed,
- especially if it is not actually used in any methods you need from the target language.
- Imagine you are wrapping the following <tt>Outer</tt> class which contains a nested class <tt>Inner</tt>.
- The easiest thing to do is turn a blind eye to the warning that SWIG generates, or simply suppress it:
- </p>
- <div class="code">
- <pre>
- %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner;
- class Outer {
- public:
- class Inner {
- public:
- ...
- };
- Inner getInner();
- void useInner(const Inner& inner);
- ...
- };
- </pre>
- </div>
- <p>
- Note that if <tt>Inner</tt> can be used as an opaque type, the default wrapping approach suffices.
- For example, if the nested class does not need to be created from the target language, but can be obtained via a method
- call, such as the <tt>getInner()</tt> method above, the returned value can then be passed around, such as passed into the
- <tt>useInner()</tt> method.
- </p>
- <p>
- With some more effort the above situation can be improved somewhat and a nested class can be constructed and used
- from the target language much like any other non-nested class. Assuming we have the <tt>Outer</tt> class in a header file:
- </p>
- <div class="code">
- <pre>
- // File outer.h
- class Outer {
- public:
- class Inner {
- public:
- int var;
- Inner(int v = 0) : var(v) {}
- };
- Inner getInner();
- void useInner(const Inner& inner);
- };
- </pre>
- </div>
- <p>
- The following interface file works around the nested class limitations by redefining the nested class as a global class.
- A typedef for the compiler and the <tt>nestedworkaround</tt>
- <a href="Customization.html#Customization_feature_flags">feature flag</a> is also required in
- order for the generated wrappers to compile. This flag simply removes all the type information from SWIG, so SWIG treats
- the nested class as if it had not been parsed at all.
- </p>
- <div class="code">
- <pre>
- // File : example.i
- %module example
- // Redefine nested class in global scope in order for SWIG to generate
- // a proxy class. Only SWIG parses this definition.
- class Inner {
- public:
- int var;
- Inner(int v = 0) : var(v) {}
- };
- %nestedworkaround Outer::Inner;
- %{
- #include "outer.h"
- %}
- %include "outer.h"
- // We've fooled SWIG into thinking that Inner is a global class, so now we need
- // to trick the C++ compiler into understanding this apparent global type.
- %{
- typedef Outer::Inner Inner;
- %}
- </pre>
- </div>
- <p>
- The downside to this approach is a more complex interface file and having to maintain two definitions of <tt>Inner</tt>,
- the real one and the one in the interface file that SWIG parses.
- However, the upside is that all the methods/variables in the nested class are available from the target language
- as a proxy class is generated instead of treating the nested class as an opaque type.
- The proxy class can be constructed from the target language and passed into any methods accepting the nested class.
- Also note that the original header file is parsed unmodified.
- </p>
- <p>
- Finally, conditional compilation can be used as a workaround to comment out nested class definitions in the actual headers,
- assuming you are able to modify them.
- </p>
- <div class="code">
- <pre>
- // File outer.h
- class Outer {
- public:
- #ifndef SWIG
- class Inner {
- public:
- ...
- };
- #endif
- ...
- };
- </pre>
- </div>
- <p>
- This workaround used to be common when SWIG could not deal with nested classes particulary well.
- This should just be a last resort for unusual corner cases now as SWIG can parse nested classes and even handle nested template classes fairly well.
- </p>
- <p>
- <b>Compatibility Note:</b> SWIG-1.3.40 and earlier versions did not have the <tt>nestedworkaround</tt> feature
- and the generated code resulting from parsing nested classes did not always compile.
- Nested class warnings could also not be suppressed using %warnfilter.
- </p>
- <H2><a name="SWIGPlus_nn37"></a>6.27 A brief rant about const-correctness</H2>
- <p>
- A common issue when working with C++ programs is dealing with all
- possible ways in which the <tt>const</tt> qualifier (or lack thereof)
- will break your program, all programs linked against your program, and
- all programs linked against those programs.
- </p>
- <p>
- Although SWIG knows how to correctly deal with <tt>const</tt> in its
- internal type system and it knows how to generate wrappers that are
- free of const-related warnings, SWIG does not make any attempt to preserve
- const-correctness in the target language. Thus, it is possible to
- pass <tt>const</tt> qualified objects to non-const methods and functions.
- For example, consider the following code in C++:
- </p>
- <div class="code">
- <pre>
- const Object * foo();
- void bar(Object *);
- ...
- // C++ code
- void blah() {
- bar(foo()); // Error: bar discards const
- };
- </pre>
- </div>
- <p>
- Now, consider the behavior when wrapped into a Python module:
- </p>
- <div class="targetlang">
- <pre>
- >>> bar(foo()) # Okay
- >>>
- </pre>
- </div>
- <p>
- Although this is clearly a violation of the C++ type-system, fixing
- the problem doesn't seem to be worth the added implementation
- complexity that would be required to support it in the SWIG run-time type
- system. There are no plans to change this in future releases
- (although we'll never rule anything out entirely).
- </p>
- <p>
- The bottom line is that this particular issue does not appear to be a problem
- for most SWIG projects. Of course, you might want to consider
- using another tool if maintaining constness is the most important part
- of your project.
- </p>
- <H2><a name="SWIGPlus_nn42"></a>6.28 Where to go for more information</H2>
- <p>
- If you're wrapping serious C++ code, you might want to pick up a copy
- of "The Annotated C++ Reference Manual" by Ellis and Stroustrup. This
- is the reference document we use to guide a lot of SWIG's C++ support.
- </p>
- </body>
- </html>
- <!-- LocalWords: destructors Enums Namespaces const SWIG's STL OO adaptor tcl
- -->
- <!-- LocalWords: debuggable cxx OBJS Wiki accessor nodefault makedefault
- -->
- <!-- LocalWords: notabstract CopyFoo
- -->