blob: f34b6c5533f88769a93de61c980a33d13eb4f7e2 [file] [log] [blame]
SWIG Myths
<h2>SWIG Myths</h2>
<p>
Here are some common misconceptions about SWIG that have occasionally
appeared on other web pages and in articles--especially those that
describe older SWIG versions.
<h4><font color="#ff0000">Myth: SWIG only really works with ANSI C</font></h4>
<h4>Fact:</h4>
SWIG <em>does</em> provide wrapping support for all of ANSI C. However, SWIG has
also included C++ support since its initial release in 1996. To be fair, early
SWIG releases had limitations, but C++ support has continually improved with
each SWIG release.
<p>
C++ support in current SWIG releases is quite advanced--providing support for nearly
every C++ feature including templates, namespaces, operators, overloaded methods,
and more. The only major C++ feature not supported is nested classes---and we're
working on that. See the <a href="compare.html">Features</a> page for more information.
<h4><font color="#ff0000">Myth: SWIG wraps C++ into this unusable
low-level "C-tran" interface.</font></h4>
<h4>Fact:</h4>
When wrapping C++, SWIG <em>does</em> generate a set of low-level procedural
wrappers. However, these are only used as building blocks for
creating a more advanced high-level wrappers (in fact, users rarely
interact with this layer directly). In nearly all target languages,
SWIG wraps C++ classes into a nice object-oriented interface that
mirrors the underlying C++ code. In Python, C++ classes
are wrapped as Python classes, in Perl, C++ classes are wrapped as
Perl classes, and so forth. The existence of procedural wrappers is
only an artifact of SWIG's layered approach to wrapper code generation.
<h4><font color="#ff0000">Myth: SWIG doesn't support overloaded methods/functions</font></h4>
<h4>Fact:</h4>
SWIG provides full support for C++ overloaded methods and functions.
For example, if you have declarations like this:
<blockquote>
<pre>
class Foo {
public:
Foo();
Foo(const Foo &amp;);
void spam(int x);
void spam(double x);
void spam(char *x, int n);
};
</pre>
</blockquote>
They can be used in a completely natural way from most SWIG language modules. For example,
in Python:
<blockquote>
<pre>
>>> f = Foo()
>>> f.spam(3)
>>> f.spam(3.5)
>>> f.spam("hello",5)
>>> g = Foo(f) # Make a copy
</pre>
</blockquote>
Or in Tcl:
<blockquote>
<pre>
% Foo f
% f spam 3
% f spam 3.5
% f spam "hello" 5
% Foo g f
</pre>
</blockquote>
The SWIG implementation of overloading utilizes type categories and a
type precedence scheme that results in the generation of dynamic
dispatch functions. The order in which declarations appear does not matter nor
does SWIG rely on unreliable mechanisms like trial execution (i.e., trying methods
one by one until one happens to execute successfully). Overloading support in SWIG
is more advanced than that.
<P>
Due to the dynamic nature of scripting languages, it is not possible to
fully disambiguate overloaded methods to the same degree as in C++.
For example, you might have declarations like this:
<blockquote>
<pre>
int foo(int);
long foo(long);
</pre>
</blockquote>
In this case, SWIG provides a number of directives to either rename or ignore
one of the declarations. For example:
<blockquote>
<pre>
%ignore foo(long);
</pre>
</blockquote>
or
<blockquote>
<pre>
%rename(foo_long) foo(long);
</pre>
</blockquote>
<h4><font color="#ff0000">Myth: SWIG doesn't support basic idiomatic C++ constructs like templates and smart pointers</font></h4>
<h4>Fact:</h4>
SWIG fully supports templates. However, to wrap a template class, you have to
tell SWIG about a particular instantiation. This is easy, just make sure SWIG
knows about the template definition and include a special directive like this:
<blockquote>
<pre>
%template(deque_int) std::deque&lt;int&gt;;
</pre>
</blockquote>
In this case, "deque_int" becomes the target language name for the wrapped object.
You would use it just like a normal class in the extension module:
<blockquote>
<pre>
>>> d = deque_int(100)
>>> d.size()
100
>>>
</pre>
</blockquote>
On the subject of smart-pointers, those are supported too. For example, suppose
you had some code like this:
<blockquote>
<pre>
class Foo {
public:
int x;
int spam(int x);
};
template&lt;class T&gt; class SmartPtr {
public:
...
T *operator-&gt;();
...
};
typedef SmartPtr&lt;Foo&gt; FooPtr;
FooPtr make_Foo();
</pre>
</blockquote>
To wrap this with SWIG, just tell it about a template instantiation. For example:
<blockquote>
<pre>
%template(FooPtr) SmartPtr&lt;Foo&gt;;
</pre>
</blockquote>
Now, in the target language, the wrapper object works just like you would expect:
<blockquote>
<pre>
>>> f = make_Foo()
>>> f.x = 3
>>> f.spam(42)
</pre>
</blockquote>
<h4><font color="#ff0000">Myth: SWIG is just too confusing to use</font></h4>
<h4>Fact:</h4>
Most users find SWIG to be relatively easy to use. However, confusion can arise
from the following:
<ul>
<li><p>C programming. To effectively use SWIG, you should have a good grasp of
basic C programming concepts like pointers, arrays, memory management, data structures,
functions, parameter passing semantics, and so forth. SWIG tries to make it easy for
C programmers to build extension modules, but it does not try to make C programming
easy.
<li><p>C++. This language is so large and complicated that certain parts of SWIG
may not make any sense unless you are also familiar with the underlying C++ concepts.
<li><p>Dynamic linking and shared libraries. To build extension modules, you usually
have to create DLLs. If you've never done this before, there is a small
learning curve associated with finding the right compiler and linker options.
<li><p>Customization features. SWIG provides a large number of customization features and
options that can be used to control almost all parts of the wrapper generation
process. These are provided to better support power users and to provide the
flexibility needed to solve difficult real-world wrapping problems. However,
none of this is needed to get started.
</ul>