SIP4 python bindings generator for TQt
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

732 lines
52 KiB

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Using SIP &mdash; SIP 4.10.5 Reference Guide</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '#',
VERSION: '4.10.5',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
<link rel="next" title="The SIP Command Line" href="command_line.html" />
<link rel="prev" title="Installation" href="installation.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="modindex.html" title="Global Module Index"
accesskey="M">modules</a> |</li>
<li class="right" >
<a href="command_line.html" title="The SIP Command Line"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="installation.html" title="Installation"
accesskey="P">previous</a> |</li>
<li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="using-sip">
<span id="ref-using"></span><h1>Using SIP<a class="headerlink" href="#using-sip" title="Permalink to this headline"></a></h1>
<p>Bindings are generated by the SIP code generator from a number of specification
files, typically with a <tt class="docutils literal"><span class="pre">.sip</span></tt> extension. Specification files look very
similar to C and C++ header files, but often with additional information (in
the form of a <em>directive</em> or an <em>annotation</em>) and code so that the bindings
generated can be finely tuned.</p>
<div class="section" id="a-simple-c-example">
<span id="ref-simple-c-example"></span><h2>A Simple C++ Example<a class="headerlink" href="#a-simple-c-example" title="Permalink to this headline"></a></h2>
<p>We start with a simple example. Let&#8217;s say you have a (fictional) C++ library
that implements a single class called <tt class="docutils literal"><span class="pre">Word</span></tt>. The class has one constructor
that takes a <tt class="docutils literal"><span class="pre">\0</span></tt> terminated character string as its single argument. The
class has one method called <tt class="docutils literal"><span class="pre">reverse()</span></tt> which takes no arguments and returns
a <tt class="docutils literal"><span class="pre">\0</span></tt> terminated character string. The interface to the class is defined in
a header file called <tt class="docutils literal"><span class="pre">word.h</span></tt> which might look something like this:</p>
<div class="highlight-python"><pre>// Define the interface to the word library.
class Word {
const char *the_word;
public:
Word(const char *w);
char *reverse() const;
};</pre>
</div>
<p>The corresponding SIP specification file would then look something like this:</p>
<div class="highlight-python"><pre>// Define the SIP wrapper to the word library.
%Module word 0
class Word {
%TypeHeaderCode
#include &lt;word.h&gt;
%End
public:
Word(const char *w);
char *reverse() const;
};</pre>
</div>
<p>Obviously a SIP specification file looks very much like a C++ (or C) header
file, but SIP does not include a full C++ parser. Let&#8217;s look at the
differences between the two files.</p>
<blockquote>
<ul class="simple">
<li>The <a class="reference external" href="directives.html#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> directive has been added <a class="footnote-reference" href="#id4" id="id1">[1]</a>. This is used to
name the Python module that is being created and to give it a
<em>generation</em> number. In this example these are <tt class="docutils literal"><span class="pre">word</span></tt> and <tt class="docutils literal"><span class="pre">0</span></tt>
respectively. The generation number is effectively the version number of
the module.</li>
<li>The <a class="reference external" href="directives.html#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a> directive has been added. The text
between this and the following <a class="reference external" href="directives.html#directive-%End"><tt class="xref docutils literal"><span class="pre">%End</span></tt></a> directive is included
literally in the code that SIP generates. Normally it is used, as in
this case, to <tt class="docutils literal"><span class="pre">#include</span></tt> the corresponding C++ (or C) header file <a class="footnote-reference" href="#id5" id="id2">[2]</a>.</li>
<li>The declaration of the private variable <tt class="docutils literal"><span class="pre">this_word</span></tt> has been removed.
SIP does not support access to either private or protected instance
variables.</li>
</ul>
</blockquote>
<p>If we want to we can now generate the C++ code in the current directory by
running the following command:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">sip</span> <span class="o">-</span><span class="n">c</span> <span class="o">.</span> <span class="n">word</span><span class="o">.</span><span class="n">sip</span>
</pre></div>
</div>
<p>However, that still leaves us with the task of compiling the generated code and
linking it against all the necessary libraries. It&#8217;s much easier to use the
<a class="reference external" href="build_system.html#ref-build-system"><em>SIP build system</em></a> to do the whole thing.</p>
<p>Using the SIP build system is simply a matter of writing a small Python script.
In this simple example we will assume that the <tt class="docutils literal"><span class="pre">word</span></tt> library we are wrapping
and it&#8217;s header file are installed in standard system locations and will be
found by the compiler and linker without having to specify any additional
flags. In a more realistic example your Python script may take command line
options, or search a set of directories to deal with different configurations
and installations.</p>
<p>This is the simplest script (conventionally called <tt class="docutils literal"><span class="pre">configure.py</span></tt>):</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">sipconfig</span>
<span class="c"># The name of the SIP build file generated by SIP and used by the build</span>
<span class="c"># system.</span>
<span class="n">build_file</span> <span class="o">=</span> <span class="s">&quot;word.sbf&quot;</span>
<span class="c"># Get the SIP configuration information.</span>
<span class="n">config</span> <span class="o">=</span> <span class="n">sipconfig</span><span class="o">.</span><span class="n">Configuration</span><span class="p">()</span>
<span class="c"># Run SIP to generate the code.</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">config</span><span class="o">.</span><span class="n">sip_bin</span><span class="p">,</span> <span class="s">&quot;-c&quot;</span><span class="p">,</span> <span class="s">&quot;.&quot;</span><span class="p">,</span> <span class="s">&quot;-b&quot;</span><span class="p">,</span> <span class="n">build_file</span><span class="p">,</span> <span class="s">&quot;word.sip&quot;</span><span class="p">]))</span>
<span class="c"># Create the Makefile.</span>
<span class="n">makefile</span> <span class="o">=</span> <span class="n">sipconfig</span><span class="o">.</span><span class="n">SIPModuleMakefile</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="n">build_file</span><span class="p">)</span>
<span class="c"># Add the library we are wrapping. The name doesn&#39;t include any platform</span>
<span class="c"># specific prefixes or extensions (e.g. the &quot;lib&quot; prefix on UNIX, or the</span>
<span class="c"># &quot;.dll&quot; extension on Windows).</span>
<span class="n">makefile</span><span class="o">.</span><span class="n">extra_libs</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;word&quot;</span><span class="p">]</span>
<span class="c"># Generate the Makefile itself.</span>
<span class="n">makefile</span><span class="o">.</span><span class="n">generate</span><span class="p">()</span>
</pre></div>
</div>
<p>Hopefully this script is self-documenting. The key parts are the
<tt class="docutils literal"><span class="pre">Configuration</span></tt> and <tt class="docutils literal"><span class="pre">SIPModuleMakefile</span></tt> classes. The build system contains
other Makefile classes, for example to build programs or to call other
Makefiles in sub-directories.</p>
<p>After running the script (using the Python interpreter the extension module is
being created for) the generated C++ code and <tt class="docutils literal"><span class="pre">Makefile</span></tt> will be in the
current directory.</p>
<p>To compile and install the extension module, just run the following
commands <a class="footnote-reference" href="#id6" id="id3">[3]</a>:</p>
<div class="highlight-python"><pre>make
make install</pre>
</div>
<p>That&#8217;s all there is to it.</p>
<p>See <a class="reference external" href="distutils.html#ref-distutils"><em>Building Your Extension with distutils</em></a> for an example of how to build this example using
distutils.</p>
<table class="docutils footnote" frame="void" id="id4" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>All SIP directives start with a <tt class="docutils literal"><span class="pre">%</span></tt> as the first non-whitespace
character of a line.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id5" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2">[2]</a></td><td>SIP includes many code directives like this. They differ in where the
supplied code is placed by SIP in the generated code.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id6" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id3">[3]</a></td><td>On Windows you might run <tt class="docutils literal"><span class="pre">nmake</span></tt> or <tt class="docutils literal"><span class="pre">mingw32-make</span></tt> instead.</td></tr>
</tbody>
</table>
</div>
<div class="section" id="id7">
<h2>A Simple C Example<a class="headerlink" href="#id7" title="Permalink to this headline"></a></h2>
<p>Let&#8217;s now look at a very similar example of wrapping a fictional C library:</p>
<div class="highlight-python"><pre>/* Define the interface to the word library. */
struct Word {
const char *the_word;
};
struct Word *create_word(const char *w);
char *reverse(struct Word *word);</pre>
</div>
<p>The corresponding SIP specification file would then look something like this:</p>
<div class="highlight-python"><pre>/* Define the SIP wrapper to the word library. */
%CModule word 0
struct Word {
%TypeHeaderCode
#include &lt;word.h&gt;
%End
const char *the_word;
};
struct Word *create_word(const char *w) /Factory/;
char *reverse(struct Word *word);</pre>
</div>
<p>Again, let&#8217;s look at the differences between the two files.</p>
<blockquote>
<ul class="simple">
<li>The <a class="reference external" href="directives.html#directive-%CModule"><tt class="xref docutils literal"><span class="pre">%CModule</span></tt></a> directive has been added. This has the same
syntax as the <a class="reference external" href="directives.html#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> directive used in the previous example
but tells SIP that the library being wrapped is implemented in C rather
than C++.</li>
<li>The <a class="reference external" href="directives.html#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a> directive has been added.</li>
<li>The <a class="reference external" href="annotations.html#fanno-Factory"><tt class="xref docutils literal"><span class="pre">Factory</span></tt></a> annotation has been added to the <tt class="docutils literal"><span class="pre">create_word()</span></tt>
function. This tells SIP that a newly created structure is being
returned and it is owned by Python.</li>
</ul>
</blockquote>
<p>The <tt class="docutils literal"><span class="pre">configure.py</span></tt> build system script described in the previous example can
be used for this example without change.</p>
</div>
<div class="section" id="a-more-complex-c-example">
<h2>A More Complex C++ Example<a class="headerlink" href="#a-more-complex-c-example" title="Permalink to this headline"></a></h2>
<p>In this last example we will wrap a fictional C++ library that contains a class
that is derived from a TQt class. This will demonstrate how SIP allows a class
hierarchy to be split across multiple Python extension modules, and will
introduce SIP&#8217;s versioning system.</p>
<p>The library contains a single C++ class called <tt class="docutils literal"><span class="pre">Hello</span></tt> which is derived from
TQt&#8217;s <tt class="docutils literal"><span class="pre">TQLabel</span></tt> class. It behaves just like <tt class="docutils literal"><span class="pre">TQLabel</span></tt> except that the text
in the label is hard coded to be <tt class="docutils literal"><span class="pre">Hello</span> <span class="pre">World</span></tt>. To make the example more
interesting we&#8217;ll also say that the library only supports TQt v4.2 and later,
and also includes a function called <tt class="docutils literal"><span class="pre">setDefault()</span></tt> that is not implemented
in the Windows version of the library.</p>
<p>The <tt class="docutils literal"><span class="pre">hello.h</span></tt> header file looks something like this:</p>
<div class="highlight-python"><pre>// Define the interface to the hello library.
#include &lt;qlabel.h&gt;
#include &lt;qwidget.h&gt;
#include &lt;qstring.h&gt;
class Hello : public TQLabel {
// This is needed by the TQt Meta-Object Compiler.
Q_OBJECT
TQ_OBJECT
public:
Hello(TQWidget *parent = 0);
private:
// Prevent instances from being copied.
Hello(const Hello &amp;);
Hello &amp;operator=(const Hello &amp;);
};
#if !defined(Q_OS_WIN)
void setDefault(const TQString &amp;def);
#endif</pre>
</div>
<p>The corresponding SIP specification file would then look something like this:</p>
<div class="highlight-python"><pre>// Define the SIP wrapper to the hello library.
%Module hello 0
%Import TQtGui/TQtGuimod.sip
%If (TQt_4_2_0 -)
class Hello : TQLabel {
%TypeHeaderCode
#include &lt;hello.h&gt;
%End
public:
Hello(TQWidget *parent /TransferThis/ = 0);
private:
Hello(const Hello &amp;);
};
%If (!WS_WIN)
void setDefault(const TQString &amp;def);
%End
%End</pre>
</div>
<p>Again we look at the differences, but we&#8217;ll skip those that we&#8217;ve looked at in
previous examples.</p>
<blockquote>
<ul class="simple">
<li>The <a class="reference external" href="directives.html#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> directive has been added to specify that we are
extending the class hierarchy defined in the file <tt class="docutils literal"><span class="pre">TQtGui/TQtGuimod.sip</span></tt>.
This file is part of PyTQt. The build system will take care of finding
the file&#8217;s exact location.</li>
<li>The <a class="reference external" href="directives.html#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directive has been added to specify that everything
<a class="footnote-reference" href="#id11" id="id8">[4]</a> up to the matching <a class="reference external" href="directives.html#directive-%End"><tt class="xref docutils literal"><span class="pre">%End</span></tt></a> directive only applies to TQt
v4.2 and later. <tt class="docutils literal"><span class="pre">TQt_4_2_0</span></tt> is a <em>tag</em> defined in <tt class="docutils literal"><span class="pre">TQtCoremod.sip</span></tt>
<a class="footnote-reference" href="#id12" id="id9">[5]</a> using the <a class="reference external" href="directives.html#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a> directive. <a class="reference external" href="directives.html#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a>
is used to define a tag for each version of a library&#8217;s API you are
wrapping allowing you to maintain all the different versions in a single
SIP specification. The build system provides support to <tt class="docutils literal"><span class="pre">configure.py</span></tt>
scripts for working out the correct tags to use according to which
version of the library is actually installed.</li>
<li>The <tt class="docutils literal"><span class="pre">public</span></tt> keyword used in defining the super-classes has been
removed. This is not supported by SIP.</li>
<li>The <a class="reference external" href="annotations.html#aanno-TransferThis"><tt class="xref docutils literal"><span class="pre">TransferThis</span></tt></a> annotation has been added to the constructor&#8217;s
argument. It specifies that if the argument is not 0 (i.e. the <tt class="docutils literal"><span class="pre">Hello</span></tt>
instance being constructed has a parent) then ownership of the instance
is transferred from Python to C++. It is needed because TQt maintains
objects (i.e. instances derived from the <tt class="docutils literal"><span class="pre">TQObject</span></tt> class) in a
hierachy. When an object is destroyed all of its children are also
automatically destroyed. It is important, therefore, that the Python
garbage collector doesn&#8217;t also try and destroy them. This is covered in
more detail in <a class="reference internal" href="#ref-object-ownership"><em>Ownership of Objects</em></a>. SIP provides many other
annotations that can be applied to arguments, functions and classes.
Multiple annotations are separated by commas. Annotations may have
values.</li>
<li>The <tt class="docutils literal"><span class="pre">=</span></tt> operator has been removed. This operator is not supported by
SIP.</li>
<li>The <a class="reference external" href="directives.html#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directive has been added to specify that everything
up to the matching <a class="reference external" href="directives.html#directive-%End"><tt class="xref docutils literal"><span class="pre">%End</span></tt></a> directive does not apply to Windows.
<tt class="docutils literal"><span class="pre">WS_WIN</span></tt> is another tag defined by PyTQt, this time using the
<a class="reference external" href="directives.html#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a> directive. Tags defined by the
<a class="reference external" href="directives.html#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a> directive are mutually exclusive, i.e. only one
may be valid at a time <a class="footnote-reference" href="#id13" id="id10">[6]</a>.</li>
</ul>
</blockquote>
<p>One question you might have at this point is why bother to define the private
copy constructor when it can never be called from Python? The answer is to
prevent the automatic generation of a public copy constructor.</p>
<p>We now look at the <tt class="docutils literal"><span class="pre">configure.py</span></tt> script. This is a little different to the
script in the previous examples for two related reasons.</p>
<p>Firstly, PyTQt includes a pure Python module called <tt class="docutils literal"><span class="pre">pyqtconfig</span></tt> that extends
the SIP build system for modules, like our example, that build on top of PyTQt.
It deals with the details of which version of TQt is being used (i.e. it
determines what the correct tags are) and where it is installed. This is
called a module&#8217;s configuration module.</p>
<p>Secondly, we generate a configuration module (called <tt class="docutils literal"><span class="pre">helloconfig</span></tt>) for our
own <tt class="docutils literal"><span class="pre">hello</span></tt> module. There is no need to do this, but if there is a chance
that somebody else might want to extend your C++ library then it would make
life easier for them.</p>
<p>Now we have two scripts. First the <tt class="docutils literal"><span class="pre">configure.py</span></tt> script:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">sipconfig</span>
<span class="kn">from</span> <span class="nn">PyTQt4</span> <span class="kn">import</span> <span class="n">pyqtconfig</span>
<span class="c"># The name of the SIP build file generated by SIP and used by the build</span>
<span class="c"># system.</span>
<span class="n">build_file</span> <span class="o">=</span> <span class="s">&quot;hello.sbf&quot;</span>
<span class="c"># Get the PyTQt configuration information.</span>
<span class="n">config</span> <span class="o">=</span> <span class="n">pyqtconfig</span><span class="o">.</span><span class="n">Configuration</span><span class="p">()</span>
<span class="c"># Get the extra SIP flags needed by the imported PyTQt modules. Note that</span>
<span class="c"># this normally only includes those flags (-x and -t) that relate to SIP&#39;s</span>
<span class="c"># versioning system.</span>
<span class="n">pyqt_sip_flags</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">pyqt_sip_flags</span>
<span class="c"># Run SIP to generate the code. Note that we tell SIP where to find the qt</span>
<span class="c"># module&#39;s specification files using the -I flag.</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">config</span><span class="o">.</span><span class="n">sip_bin</span><span class="p">,</span> <span class="s">&quot;-c&quot;</span><span class="p">,</span> <span class="s">&quot;.&quot;</span><span class="p">,</span> <span class="s">&quot;-b&quot;</span><span class="p">,</span> <span class="n">build_file</span><span class="p">,</span> <span class="s">&quot;-I&quot;</span><span class="p">,</span> <span class="n">config</span><span class="o">.</span><span class="n">pyqt_sip_dir</span><span class="p">,</span> <span class="n">pyqt_sip_flags</span><span class="p">,</span> <span class="s">&quot;hello.sip&quot;</span><span class="p">]))</span>
<span class="c"># We are going to install the SIP specification file for this module and</span>
<span class="c"># its configuration module.</span>
<span class="n">installs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">installs</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="s">&quot;hello.sip&quot;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">default_sip_dir</span><span class="p">,</span> <span class="s">&quot;hello&quot;</span><span class="p">)])</span>
<span class="n">installs</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="s">&quot;helloconfig.py&quot;</span><span class="p">,</span> <span class="n">config</span><span class="o">.</span><span class="n">default_mod_dir</span><span class="p">])</span>
<span class="c"># Create the Makefile. The TQtGuiModuleMakefile class provided by the</span>
<span class="c"># pyqtconfig module takes care of all the extra preprocessor, compiler and</span>
<span class="c"># linker flags needed by the TQt library.</span>
<span class="n">makefile</span> <span class="o">=</span> <span class="n">pyqtconfig</span><span class="o">.</span><span class="n">TQtGuiModuleMakefile</span><span class="p">(</span>
<span class="n">configuration</span><span class="o">=</span><span class="n">config</span><span class="p">,</span>
<span class="n">build_file</span><span class="o">=</span><span class="n">build_file</span><span class="p">,</span>
<span class="n">installs</span><span class="o">=</span><span class="n">installs</span>
<span class="p">)</span>
<span class="c"># Add the library we are wrapping. The name doesn&#39;t include any platform</span>
<span class="c"># specific prefixes or extensions (e.g. the &quot;lib&quot; prefix on UNIX, or the</span>
<span class="c"># &quot;.dll&quot; extension on Windows).</span>
<span class="n">makefile</span><span class="o">.</span><span class="n">extra_libs</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;hello&quot;</span><span class="p">]</span>
<span class="c"># Generate the Makefile itself.</span>
<span class="n">makefile</span><span class="o">.</span><span class="n">generate</span><span class="p">()</span>
<span class="c"># Now we create the configuration module. This is done by merging a Python</span>
<span class="c"># dictionary (whose values are normally determined dynamically) with a</span>
<span class="c"># (static) template.</span>
<span class="n">content</span> <span class="o">=</span> <span class="p">{</span>
<span class="c"># Publish where the SIP specifications for this module will be</span>
<span class="c"># installed.</span>
<span class="s">&quot;hello_sip_dir&quot;</span><span class="p">:</span> <span class="n">config</span><span class="o">.</span><span class="n">default_sip_dir</span><span class="p">,</span>
<span class="c"># Publish the set of SIP flags needed by this module. As these are the</span>
<span class="c"># same flags needed by the qt module we could leave it out, but this</span>
<span class="c"># allows us to change the flags at a later date without breaking</span>
<span class="c"># scripts that import the configuration module.</span>
<span class="s">&quot;hello_sip_flags&quot;</span><span class="p">:</span> <span class="n">pyqt_sip_flags</span>
<span class="p">}</span>
<span class="c"># This creates the helloconfig.py module from the helloconfig.py.in</span>
<span class="c"># template and the dictionary.</span>
<span class="n">sipconfig</span><span class="o">.</span><span class="n">create_config_module</span><span class="p">(</span><span class="s">&quot;helloconfig.py&quot;</span><span class="p">,</span> <span class="s">&quot;helloconfig.py.in&quot;</span><span class="p">,</span> <span class="n">content</span><span class="p">)</span>
</pre></div>
</div>
<p>Next we have the <tt class="docutils literal"><span class="pre">helloconfig.py.in</span></tt> template script:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">PyTQt4</span> <span class="kn">import</span> <span class="n">pyqtconfig</span>
<span class="c"># These are installation specific values created when Hello was configured.</span>
<span class="c"># The following line will be replaced when this template is used to create</span>
<span class="c"># the final configuration module.</span>
<span class="c"># @SIP_CONFIGURATION@</span>
<span class="k">class</span> <span class="nc">Configuration</span><span class="p">(</span><span class="n">pyqtconfig</span><span class="o">.</span><span class="n">Configuration</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;The class that represents Hello configuration values.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub_cfg</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Initialise an instance of the class.</span>
<span class="sd"> sub_cfg is the list of sub-class configurations. It should be None</span>
<span class="sd"> when called normally.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c"># This is all standard code to be copied verbatim except for the</span>
<span class="c"># name of the module containing the super-class.</span>
<span class="k">if</span> <span class="n">sub_cfg</span><span class="p">:</span>
<span class="n">cfg</span> <span class="o">=</span> <span class="n">sub_cfg</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">cfg</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">cfg</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_pkg_config</span><span class="p">)</span>
<span class="n">pyqtconfig</span><span class="o">.</span><span class="n">Configuration</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cfg</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">HelloModuleMakefile</span><span class="p">(</span><span class="n">pyqtconfig</span><span class="o">.</span><span class="n">TQtGuiModuleMakefile</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;The Makefile class for modules that %Import hello.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">finalise</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Finalise the macros.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c"># Make sure our C++ library is linked.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra_libs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;hello&quot;</span><span class="p">)</span>
<span class="c"># Let the super-class do what it needs to.</span>
<span class="n">pyqtconfig</span><span class="o">.</span><span class="n">TQtGuiModuleMakefile</span><span class="o">.</span><span class="n">finalise</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
</pre></div>
</div>
<p>Again, we hope that the scripts are self documenting.</p>
<table class="docutils footnote" frame="void" id="id11" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id8">[4]</a></td><td>Some parts of a SIP specification aren&#8217;t subject to version control.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id12" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id9">[5]</a></td><td>Actually in <tt class="docutils literal"><span class="pre">versions.sip</span></tt>. PyTQt uses the <a class="reference external" href="directives.html#directive-%Include"><tt class="xref docutils literal"><span class="pre">%Include</span></tt></a>
directive to split the SIP specification for TQt across a large number of
separate <tt class="docutils literal"><span class="pre">.sip</span></tt> files.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id13" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id10">[6]</a></td><td>Tags can also be defined by the <a class="reference external" href="directives.html#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> directive. These
tags are not mutually exclusive, i.e. any number may be valid at a time.</td></tr>
</tbody>
</table>
</div>
<div class="section" id="ownership-of-objects">
<span id="ref-object-ownership"></span><h2>Ownership of Objects<a class="headerlink" href="#ownership-of-objects" title="Permalink to this headline"></a></h2>
<p>When a C++ instance is wrapped a corresponding Python object is created. The
Python object behaves as you would expect in regard to garbage collection - it
is garbage collected when its reference count reaches zero. What then happens
to the corresponding C++ instance? The obvious answer might be that the
instance&#8217;s destructor is called. However the library API may say that when the
instance is passed to a particular function, the library takes ownership of the
instance, i.e. responsibility for calling the instance&#8217;s destructor is
transferred from the SIP generated module to the library.</p>
<p>Ownership of an instance may also be associated with another instance. The
implication being that the owned instance will automatically be destroyed if
the owning instance is destroyed. SIP keeps track of these relationships to
ensure that Python&#8217;s cyclic garbage collector can detect and break any
reference cycles between the owning and owned instances. The association is
implemented as the owning instance taking a reference to the owned instance.</p>
<p>The TransferThis, Transfer and TransferBack annotations are used to specify
where, and it what direction, transfers of ownership happen. It is very
important that these are specified correctly to avoid crashes (where both
Python and C++ call the destructor) and memory leaks (where neither Python and
C++ call the destructor).</p>
<p>This applies equally to C structures where the structure is returned to the
heap using the <tt class="docutils literal"><span class="pre">free()</span></tt> function.</p>
<p>See also <a title="sipTransferTo" class="reference external" href="c_api.html#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>, <a title="sipTransferBack" class="reference external" href="c_api.html#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a> and
<a title="sipTransferBreak" class="reference external" href="c_api.html#sipTransferBreak"><tt class="xref docutils literal"><span class="pre">sipTransferBreak()</span></tt></a>.</p>
</div>
<div class="section" id="types-and-meta-types">
<span id="ref-types-metatypes"></span><h2>Types and Meta-types<a class="headerlink" href="#types-and-meta-types" title="Permalink to this headline"></a></h2>
<p>Every Python object (with the exception of the <tt class="xref docutils literal"><span class="pre">object</span></tt> object itself)
has a meta-type and at least one super-type. By default an object&#8217;s meta-type
is the meta-type of its first super-type.</p>
<p>SIP implements two super-types, <tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt> and
<a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a>, and a meta-type, <a title="sip.wrappertype" class="reference external" href="python_api.html#sip.wrappertype"><tt class="xref docutils literal"><span class="pre">sip.wrappertype</span></tt></a>.</p>
<p><tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt> is the super-type of <a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a>. The
super-type of <tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt> is <tt class="xref docutils literal"><span class="pre">object</span></tt>.</p>
<p><a title="sip.wrappertype" class="reference external" href="python_api.html#sip.wrappertype"><tt class="xref docutils literal"><span class="pre">sip.wrappertype</span></tt></a> is the meta-type of both <tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt>
and <a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a>. The super-type of <a title="sip.wrappertype" class="reference external" href="python_api.html#sip.wrappertype"><tt class="xref docutils literal"><span class="pre">sip.wrappertype</span></tt></a> is
<tt class="xref docutils literal"><span class="pre">type</span></tt>.</p>
<p><a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a> supports the concept of object ownership described in
<a class="reference internal" href="#ref-object-ownership"><em>Ownership of Objects</em></a> and, by default, is the super-type of all the types
that SIP generates.</p>
<p><tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt> does not support the concept of object ownership but
SIP generated types that are sub-classed from it have Python objects that take
less memory.</p>
<p>SIP allows a class&#8217;s meta-type and super-type to be explicitly specified using
the <a class="reference external" href="annotations.html#canno-Metatype"><tt class="xref docutils literal"><span class="pre">Metatype</span></tt></a> and <a class="reference external" href="annotations.html#canno-Supertype"><tt class="xref docutils literal"><span class="pre">Supertype</span></tt></a> class annotations.</p>
<p>SIP also allows the default meta-type and super-type to be changed for a module
using the <a class="reference external" href="directives.html#directive-%DefaultMetatype"><tt class="xref docutils literal"><span class="pre">%DefaultMetatype</span></tt></a> and <a class="reference external" href="directives.html#directive-%DefaultSupertype"><tt class="xref docutils literal"><span class="pre">%DefaultSupertype</span></tt></a>
directives. Unlike the default super-type, the default meta-type is inherited
by importing modules.</p>
<p>If you want to use your own meta-type or super-type then they must be
sub-classed from one of the SIP provided types. Your types must be registered
using <a title="sipRegisterPyType" class="reference external" href="c_api.html#sipRegisterPyType"><tt class="xref docutils literal"><span class="pre">sipRegisterPyType()</span></tt></a>. This is normally done in code specified
using the <a class="reference external" href="directives.html#directive-%InitialisationCode"><tt class="xref docutils literal"><span class="pre">%InitialisationCode</span></tt></a> directive.</p>
<p>As an example, PyTQt4 uses <a class="reference external" href="directives.html#directive-%DefaultMetatype"><tt class="xref docutils literal"><span class="pre">%DefaultMetatype</span></tt></a> to specify a new
meta-type that handles the interaction with TQt&#8217;s own meta-type system. It also
uses <a class="reference external" href="directives.html#directive-%DefaultSupertype"><tt class="xref docutils literal"><span class="pre">%DefaultSupertype</span></tt></a> to specify that the smaller
<tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt> super-type is normally used. Finally it uses
<a class="reference external" href="annotations.html#canno-Supertype"><tt class="xref docutils literal"><span class="pre">Supertype</span></tt></a> as an annotation of the <tt class="docutils literal"><span class="pre">TQObject</span></tt> class to override the
default and use <a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a> as the super-type so that the parent/child
relationships of <tt class="docutils literal"><span class="pre">TQObject</span></tt> instances are properly maintained.</p>
</div>
<div class="section" id="lazy-type-attributes">
<span id="ref-lazy-type-attributes"></span><h2>Lazy Type Attributes<a class="headerlink" href="#lazy-type-attributes" title="Permalink to this headline"></a></h2>
<p>Instead of populating a wrapped type&#8217;s dictionary with its attributes (or
descriptors for those attributes) SIP only creates objects for those attributes
when they are actually needed. This is done to reduce the memory footprint and
start up time when used to wrap large libraries with hundreds of classes and
tens of thousands of attributes.</p>
<p>SIP allows you to extend the handling of lazy attributes to your own attribute
types by allowing you to register an attribute getter handler (using
<a title="sipRegisterAttributeGetter" class="reference external" href="c_api.html#sipRegisterAttributeGetter"><tt class="xref docutils literal"><span class="pre">sipRegisterAttributeGetter()</span></tt></a>). This will be called just before a
type&#8217;s dictionary is accessed for the first time.</p>
</div>
<div class="section" id="support-for-python-s-buffer-interface">
<h2>Support for Python&#8217;s Buffer Interface<a class="headerlink" href="#support-for-python-s-buffer-interface" title="Permalink to this headline"></a></h2>
<p>SIP supports Python&#8217;s buffer interface in that whenever C/C++ requires a
<tt class="docutils literal"><span class="pre">char</span></tt> or <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> type then any Python type that supports the buffer
interface (including ordinary Python strings) can be used.</p>
<p>If a buffer is made up of a number of segments then all but the first will be
ignored.</p>
</div>
<div class="section" id="support-for-wide-characters">
<h2>Support for Wide Characters<a class="headerlink" href="#support-for-wide-characters" title="Permalink to this headline"></a></h2>
<p>SIP v4.6 introduced support for wide characters (i.e. the <tt class="docutils literal"><span class="pre">wchar_t</span></tt> type).
Python&#8217;s C API includes support for converting between unicode objects and wide
character strings and arrays. When converting from a unicode object to wide
characters SIP creates the string or array on the heap (using memory allocated
using <a title="sipMalloc" class="reference external" href="c_api.html#sipMalloc"><tt class="xref docutils literal"><span class="pre">sipMalloc()</span></tt></a>). This then raises the problem of how this memory
is subsequently freed.</p>
<p>The following describes how SIP handles this memory in the different situations
where this is an issue.</p>
<blockquote>
<ul class="simple">
<li>When a wide string or array is passed to a function or method then the
memory is freed (using <a title="sipFree" class="reference external" href="c_api.html#sipFree"><tt class="xref docutils literal"><span class="pre">sipFree()</span></tt></a>) after than function or method
returns.</li>
<li>When a wide string or array is returned from a virtual method then SIP
does not free the memory until the next time the method is called.</li>
<li>When an assignment is made to a wide string or array instance variable
then SIP does not first free the instance&#8217;s current string or array.</li>
</ul>
</blockquote>
</div>
<div class="section" id="the-python-global-interpreter-lock">
<span id="ref-gil"></span><h2>The Python Global Interpreter Lock<a class="headerlink" href="#the-python-global-interpreter-lock" title="Permalink to this headline"></a></h2>
<p>Python&#8217;s Global Interpretor Lock (GIL) must be acquired before calls can be
made to the Python API. It should also be released when a potentially
blocking call to C/C++ library is made in order to allow other Python threads
to be executed. In addition, some C/C++ libraries may implement their own
locking strategies that conflict with the GIL causing application deadlocks.
SIP provides ways of specifying when the GIL is released and acquired to
ensure that locking problems can be avoided.</p>
<p>SIP always ensures that the GIL is acquired before making calls to the Python
API. By default SIP does not release the GIL when making calls to the C/C++
library being wrapped. The <a class="reference external" href="annotations.html#fanno-ReleaseGIL"><tt class="xref docutils literal"><span class="pre">ReleaseGIL</span></tt></a> annotation can be used to
override this behaviour when required.</p>
<p>If SIP is given the <a class="reference external" href="command_line.html#cmdoption-sip-g"><em class="xref">-g</em></a> command line option then the default
behaviour is changed and SIP releases the GIL every time is makes calls to the
C/C++ library being wrapped. The <a class="reference external" href="annotations.html#fanno-HoldGIL"><tt class="xref docutils literal"><span class="pre">HoldGIL</span></tt></a> annotation can be used to
override this behaviour when required.</p>
</div>
<div class="section" id="managing-incompatible-apis">
<span id="ref-incompat-apis"></span><h2>Managing Incompatible APIs<a class="headerlink" href="#managing-incompatible-apis" title="Permalink to this headline"></a></h2>
<p>
<span class="versionmodified">New in version 4.9.</span></p>
<p>Sometimes it is necessary to change the way something is wrapped in a way that
introduces an incompatibility. For example a new feature of Python may
suggest that something may be wrapped in a different way to exploit that
feature.</p>
<p>SIP&#8217;s <a class="reference external" href="directives.html#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> directive could be used to provide two different
implementations. However this would mean that the choice between the two
implementations would have to be made when building the generated module
potentially causing all sorts of deployment problems. It may also require
applications to work out which implementation was available and to change
their behaviour accordingly.</p>
<p>Instead SIP provides limited support for providing multiple implementations
(of classes, mapped types and functions) that can be selected by an
application at run-time. It is then up to the application developer how they
want to manage the migration from the old API to the new, incompatible API.</p>
<p>This support is implemented in three parts.</p>
<p>Firstly the <a class="reference external" href="directives.html#directive-%API"><tt class="xref docutils literal"><span class="pre">%API</span></tt></a> directive is used to define the name of an API
and its default version number. The default version number is the one used if
an application doesn&#8217;t explicitly set the version number to use.</p>
<p>Secondly the <a class="reference external" href="annotations.html#canno-API"><tt class="xref docutils literal"><span class="pre">API</span> <span class="pre">class</span></tt></a>, <a class="reference external" href="annotations.html#manno-API"><tt class="xref docutils literal"><span class="pre">mapped</span> <span class="pre">type</span></tt></a> or
<a class="reference external" href="annotations.html#fanno-API"><tt class="xref docutils literal"><span class="pre">function</span></tt></a> annotation is applied accordingly to specify the API
and range of version numbers that a particular class, mapped type or function
implementation should be enabled for.</p>
<p>Finally the application calls <a title="sip.setapi" class="reference external" href="python_api.html#sip.setapi"><tt class="xref docutils literal"><span class="pre">sip.setapi()</span></tt></a> to specify the version number
of the API that should be enabled. This call must be made before any module
that has multiple implementations is imported for the first time.</p>
<p>Note this mechanism is not intended as a way or providing equally valid
alternative APIs. For example:</p>
<div class="highlight-python"><pre>%API MyAPI 1
class Foo
{
public:
void bar();
};
class Baz : Foo
{
public:
void bar() /API=MyAPI:2-/;
};</pre>
</div>
<p>If the following Python code is executed then an exception will be raised:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">b</span> <span class="o">=</span> <span class="n">Baz</span><span class="p">()</span>
<span class="n">b</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span>
</pre></div>
</div>
<p>This is because when version 1 of the <em>MyAPI</em> API (the default) is enabled
there is no <em>Baz.bar()</em> implementation and <em>Foo.bar()</em> will not be called
instead as might be expected.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="#">Using SIP</a><ul>
<li><a class="reference external" href="#a-simple-c-example">A Simple C++ Example</a></li>
<li><a class="reference external" href="#id7">A Simple C Example</a></li>
<li><a class="reference external" href="#a-more-complex-c-example">A More Complex C++ Example</a></li>
<li><a class="reference external" href="#ownership-of-objects">Ownership of Objects</a></li>
<li><a class="reference external" href="#types-and-meta-types">Types and Meta-types</a></li>
<li><a class="reference external" href="#lazy-type-attributes">Lazy Type Attributes</a></li>
<li><a class="reference external" href="#support-for-python-s-buffer-interface">Support for Python&#8217;s Buffer Interface</a></li>
<li><a class="reference external" href="#support-for-wide-characters">Support for Wide Characters</a></li>
<li><a class="reference external" href="#the-python-global-interpreter-lock">The Python Global Interpreter Lock</a></li>
<li><a class="reference external" href="#managing-incompatible-apis">Managing Incompatible APIs</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="installation.html"
title="previous chapter">Installation</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="command_line.html"
title="next chapter">The SIP Command Line</a></p>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="modindex.html" title="Global Module Index"
>modules</a> |</li>
<li class="right" >
<a href="command_line.html" title="The SIP Command Line"
>next</a> |</li>
<li class="right" >
<a href="installation.html" title="Installation"
>previous</a> |</li>
<li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010 Riverbank Computing Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
</div>
</body>
</html>