diff options
author | Timothy Pearson <[email protected]> | 2011-11-22 02:59:34 -0600 |
---|---|---|
committer | Timothy Pearson <[email protected]> | 2011-11-22 02:59:34 -0600 |
commit | 6c4cc3653e8dd7668295f3e659b7eb4dc571b67c (patch) | |
tree | a559fd71fc982e35a4f984d85a5c9d92b764ae8c /doc/html/directives.html | |
download | sip4-tqt-6c4cc3653e8dd7668295f3e659b7eb4dc571b67c.tar.gz sip4-tqt-6c4cc3653e8dd7668295f3e659b7eb4dc571b67c.zip |
Initial import of SIP4 for Qt3
Diffstat (limited to 'doc/html/directives.html')
-rw-r--r-- | doc/html/directives.html | 2045 |
1 files changed, 2045 insertions, 0 deletions
diff --git a/doc/html/directives.html b/doc/html/directives.html new file mode 100644 index 0000000..eab1185 --- /dev/null +++ b/doc/html/directives.html @@ -0,0 +1,2045 @@ +<!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>Directives — 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="Annotations" href="annotations.html" /> + <link rel="prev" title="SIP Specification Files" href="specification_files.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="annotations.html" title="Annotations" + accesskey="N">next</a> |</li> + <li class="right" > + <a href="specification_files.html" title="SIP Specification Files" + accesskey="P">previous</a> |</li> + <li><a href="index.html">SIP 4.10.5 Reference Guide</a> »</li> + </ul> + </div> + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + <div class="body"> + + <div class="section" id="directives"> +<h1>Directives<a class="headerlink" href="#directives" title="Permalink to this headline">¶</a></h1> +<p>In this section we describe each of the directives that can be used in +specification files. All directives begin with <tt class="docutils literal"><span class="pre">%</span></tt> as the first +non-whitespace character in a line.</p> +<p>Some directives have arguments or contain blocks of code or documentation. In +the following descriptions these are shown in <em>italics</em>. Optional arguments +are enclosed in [<em>brackets</em>].</p> +<p>Some directives are used to specify handwritten code. Handwritten code must +not define names that start with the prefix <tt class="docutils literal"><span class="pre">sip</span></tt>.</p> +<dl class="directive"> +<dt id="directive-%AccessCode"> +<tt class="descname">%AccessCode</tt><a class="headerlink" href="#directive-%AccessCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%AccessCode + <em>code</em> +%End +</pre> +<p>This directive is used immediately after the declaration of an instance of a +wrapped class or structure, or a pointer to such an instance. You use it to +provide handwritten code that overrides the default behaviour.</p> +<p>For example:</p> +<div class="highlight-python"><pre>class Klass; + +Klass *klassInstance; +%AccessCode + // In this contrived example the C++ library we are wrapping defines + // klassInstance as Klass ** (which SIP doesn't support) so we + // explicitly dereference it. + if (klassInstance && *klassInstance) + return *klassInstance; + + // This will get converted to None. + return 0; +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%API"> +<tt class="descname">%API</tt><a class="headerlink" href="#directive-%API" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<p> +<span class="versionmodified">New in version 4.9.</span></p> +<pre class="literal-block"> +%API <em>name</em> <em>version</em> +</pre> +<p>This directive is used to define an API and set its default version number. A +version number must be greater than or equal to 1.</p> +<p>See <a class="reference external" href="using.html#ref-incompat-apis"><em>Managing Incompatible APIs</em></a> for more detail.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%API PyQt4 1</pre> +</div> +<dl class="directive"> +<dt id="directive-%BIGetBufferCode"> +<tt class="descname">%BIGetBufferCode</tt><a class="headerlink" href="#directive-%BIGetBufferCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%BIGetBufferCode + <em>code</em> +%End +</pre> +<p>This directive (along with <a class="reference internal" href="#directive-%BIReleaseBufferCode"><tt class="xref docutils literal"><span class="pre">%BIReleaseBufferCode</span></tt></a>) is used to +specify code that implements the buffer interface of Python v3. If Python v2 +is being used then this is ignored.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt>Py_buffer *sipBuffer</dt> +<dd>This is a pointer to the Python buffer structure that the handwritten code +must populate.</dd> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class.</dd> +<dt>int sipFlags</dt> +<dd>These are the flags that specify what elements of the <tt class="docutils literal"><span class="pre">sipBuffer</span></tt> +structure must be populated.</dd> +<dt>int sipRes</dt> +<dd>The handwritten code should set this to 0 if there was no error or -1 if +there was an error.</dd> +<dt>PyObject *sipSelf</dt> +<dd>This is the Python object that wraps the structure or class instance, i.e. +<tt class="docutils literal"><span class="pre">self</span></tt>.</dd> +</dl> +<dl class="directive"> +<dt id="directive-%BIGetCharBufferCode"> +<tt class="descname">%BIGetCharBufferCode</tt><a class="headerlink" href="#directive-%BIGetCharBufferCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%BIGetCharBufferCode + <em>code</em> +%End +</pre> +<p>This directive (along with <a class="reference internal" href="#directive-%BIGetReadBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetReadBufferCode</span></tt></a>, +<a class="reference internal" href="#directive-%BIGetSegCountCode"><tt class="xref docutils literal"><span class="pre">%BIGetSegCountCode</span></tt></a> and <a class="reference internal" href="#directive-%BIGetWriteBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetWriteBufferCode</span></tt></a>) is used +to specify code that implements the buffer interface of Python v2. If Python +v3 is being used then this is ignored.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class.</dd> +<dt>void **sipPtrPtr</dt> +<dd>This is the pointer used to return the address of the character buffer.</dd> +<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipRes</dt> +<dd>The handwritten code should set this to the length of the character buffer +or -1 if there was an error.</dd> +<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipSegment</dt> +<dd>This is the number of the segment of the character buffer.</dd> +<dt>PyObject *sipSelf</dt> +<dd>This is the Python object that wraps the structure or class instance, i.e. +<tt class="docutils literal"><span class="pre">self</span></tt>.</dd> +</dl> +<dl class="directive"> +<dt id="directive-%BIGetReadBufferCode"> +<tt class="descname">%BIGetReadBufferCode</tt><a class="headerlink" href="#directive-%BIGetReadBufferCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%BIGetReadBufferCode + <em>code</em> +%End +</pre> +<p>This directive (along with <a class="reference internal" href="#directive-%BIGetCharBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetCharBufferCode</span></tt></a>, +<a class="reference internal" href="#directive-%BIGetSegCountCode"><tt class="xref docutils literal"><span class="pre">%BIGetSegCountCode</span></tt></a> and <a class="reference internal" href="#directive-%BIGetWriteBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetWriteBufferCode</span></tt></a>) is used +to specify code that implements the buffer interface of Python v2. If +Python v3 is being used then this is ignored.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class.</dd> +<dt>void **sipPtrPtr</dt> +<dd>This is the pointer used to return the address of the read buffer.</dd> +<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipRes</dt> +<dd>The handwritten code should set this to the length of the read buffer or +-1 if there was an error.</dd> +<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipSegment</dt> +<dd>This is the number of the segment of the read buffer.</dd> +<dt>PyObject *sipSelf</dt> +<dd>This is the Python object that wraps the structure or class instance, i.e. +<tt class="docutils literal"><span class="pre">self</span></tt>.</dd> +</dl> +<dl class="directive"> +<dt id="directive-%BIGetSegCountCode"> +<tt class="descname">%BIGetSegCountCode</tt><a class="headerlink" href="#directive-%BIGetSegCountCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%BIGetSegCountCode + <em>code</em> +%End +</pre> +<p>This directive (along with <a class="reference internal" href="#directive-%BIGetCharBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetCharBufferCode</span></tt></a>, +<a class="reference internal" href="#directive-%BIGetReadBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetReadBufferCode</span></tt></a> and <a class="reference internal" href="#directive-%BIGetWriteBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetWriteBufferCode</span></tt></a>) is +used to specify code that implements the buffer interface of Python v2. If +Python v3 is being used then this is ignored.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class.</dd> +<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> *sipLenPtr</dt> +<dd>This is the pointer used to return the total length in bytes of all +segments of the buffer.</dd> +<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipRes</dt> +<dd>The handwritten code should set this to the number of segments that make +up the buffer.</dd> +<dt>PyObject *sipSelf</dt> +<dd>This is the Python object that wraps the structure or class instance, i.e. +<tt class="docutils literal"><span class="pre">self</span></tt>.</dd> +</dl> +<dl class="directive"> +<dt id="directive-%BIGetWriteBufferCode"> +<tt class="descname">%BIGetWriteBufferCode</tt><a class="headerlink" href="#directive-%BIGetWriteBufferCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%BIGetWriteBufferCode + <em>code</em> +%End +</pre> +<p>This directive (along with <a class="reference internal" href="#directive-%BIGetCharBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetCharBufferCode</span></tt></a>, +<a class="reference internal" href="#directive-%BIGetReadBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetReadBufferCode</span></tt></a> and <a class="reference internal" href="#directive-%BIGetSegCountCode"><tt class="xref docutils literal"><span class="pre">%BIGetSegCountCode</span></tt></a> is used +to specify code that implements the buffer interface of Python v2. If Python +v3 is being used then this is ignored.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class.</dd> +<dt>void **sipPtrPtr</dt> +<dd>This is the pointer used to return the address of the write buffer.</dd> +<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipRes</dt> +<dd>The handwritten code should set this to the length of the write buffer or +-1 if there was an error.</dd> +<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipSegment</dt> +<dd>This is the number of the segment of the write buffer.</dd> +<dt>PyObject *sipSelf</dt> +<dd>This is the Python object that wraps the structure or class instance, i.e. +<tt class="docutils literal"><span class="pre">self</span></tt>.</dd> +</dl> +<dl class="directive"> +<dt id="directive-%BIReleaseBufferCode"> +<tt class="descname">%BIReleaseBufferCode</tt><a class="headerlink" href="#directive-%BIReleaseBufferCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%BIReleaseBufferCode + <em>code</em> +%End +</pre> +<p>This directive (along with <a class="reference internal" href="#directive-%BIGetBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetBufferCode</span></tt></a>) is used to specify +code that implements the buffer interface of Python v3. If Python v2 is being +used then this is ignored.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt>Py_buffer *sipBuffer</dt> +<dd>This is a pointer to the Python buffer structure.</dd> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class.</dd> +<dt>PyObject *sipSelf</dt> +<dd>This is the Python object that wraps the structure or class instance, i.e. +<tt class="docutils literal"><span class="pre">self</span></tt>.</dd> +</dl> +<dl class="directive"> +<dt id="directive-%CModule"> +<tt class="descname">%CModule</tt><a class="headerlink" href="#directive-%CModule" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%CModule <em>name</em> [<em>version</em>] +</pre> +<p>This directive is used to identify that the library being wrapped is a C +library and to define the name of the module and it’s optional version number.</p> +<p>See the <a class="reference internal" href="#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> directive for an explanation of the version +number.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%CModule dbus 1</pre> +</div> +<dl class="directive"> +<dt id="directive-%CompositeModule"> +<tt class="descname">%CompositeModule</tt><a class="headerlink" href="#directive-%CompositeModule" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%CompositeModule <em>name</em> +</pre> +<p>A composite module is one that merges a number of related SIP generated +modules. For example, a module that merges the modules <tt class="docutils literal"><span class="pre">a_mod</span></tt>, <tt class="docutils literal"><span class="pre">b_mod</span></tt> +and <tt class="docutils literal"><span class="pre">c_mod</span></tt> is equivalent to the following pure Python module:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">a_mod</span> <span class="kn">import</span> <span class="o">*</span> +<span class="kn">from</span> <span class="nn">b_mod</span> <span class="kn">import</span> <span class="o">*</span> +<span class="kn">from</span> <span class="nn">c_mod</span> <span class="kn">import</span> <span class="o">*</span> +</pre></div> +</div> +<p>Clearly the individual modules should not define module-level objects with the +same name.</p> +<p>This directive is used to specify the name of a composite module. Any +subsequent <a class="reference internal" href="#directive-%CModule"><tt class="xref docutils literal"><span class="pre">%CModule</span></tt></a> or <a class="reference internal" href="#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> directive is +interpreted as defining a component module.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%CompositeModule PyQt4.Qt +%Include QtCore/QtCoremod.sip +%Include QtGui/QtGuimod.sip</pre> +</div> +<p>The main purpose of a composite module is as a programmer convenience as they +don’t have to remember which which individual module an object is defined in.</p> +<dl class="directive"> +<dt id="directive-%ConsolidatedModule"> +<tt class="descname">%ConsolidatedModule</tt><a class="headerlink" href="#directive-%ConsolidatedModule" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%ConsolidatedModule <em>name</em> +</pre> +<p>A consolidated module is one that consolidates the wrapper code of a number of +SIP generated modules (refered to as component modules in this context).</p> +<p>This directive is used to specify the name of a consolidated module. Any +subsequent <a class="reference internal" href="#directive-%CModule"><tt class="xref docutils literal"><span class="pre">%CModule</span></tt></a> or <a class="reference internal" href="#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> directive is +interpreted as defining a component module.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%ConsolidatedModule PyQt4._qt +%Include QtCore/QtCoremod.sip +%Include QtGui/QtGuimod.sip</pre> +</div> +<p>A consolidated module is not intended to be explicitly imported by an +application. Instead it is imported by its component modules when they +themselves are imported.</p> +<p>Normally the wrapper code is contained in the component module and is linked +against the corresponding C or C++ library. The advantage of a consolidated +module is that it allows all of the wrapped C or C++ libraries to be linked +against a single module. If the linking is done statically then deployment of +generated modules can be greatly simplified.</p> +<p>It follows that a component module can be built in one of two ways, as a +normal standalone module, or as a component of a consolidated module. When +building as a component the <tt class="docutils literal"><span class="pre">-p</span></tt> command line option should be used to +specify the name of the consolidated module.</p> +<dl class="directive"> +<dt id="directive-%ConvertFromTypeCode"> +<tt class="descname">%ConvertFromTypeCode</tt><a class="headerlink" href="#directive-%ConvertFromTypeCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%ConvertFromTypeCode + <em>code</em> +%End +</pre> +<p>This directive is used as part of the <a class="reference internal" href="#directive-%MappedType"><tt class="xref docutils literal"><span class="pre">%MappedType</span></tt></a> directive to +specify the handwritten code that converts an instance of a mapped type to a +Python object.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the instance of the mapped type to be converted. It +will never be zero as the conversion from zero to <tt class="docutils literal"><span class="pre">Py_None</span></tt> is handled +before the handwritten code is called.</dd> +<dt>PyObject *sipTransferObj</dt> +<dd>This specifies any desired ownership changes to the returned object. If it +is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the ownership should be left unchanged. If it is +<tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership should be transferred to Python. Otherwise +ownership should be transferred to C/C++ and the returned object associated +with <em>sipTransferObj</em>. The code can choose to interpret these changes in +any way. For example, if the code is converting a C++ container of wrapped +classes to a Python list it is likely that the ownership changes should be +made to each element of the list.</dd> +</dl> +<p>The handwritten code must explicitly return a <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt>. If there was an +error then a Python exception must be raised and <tt class="docutils literal"><span class="pre">NULL</span></tt> returned.</p> +<p>The following example converts a <tt class="docutils literal"><span class="pre">QList<QWidget</span> <span class="pre">*></span></tt> instance to a Python +list of <tt class="docutils literal"><span class="pre">QWidget</span></tt> instances:</p> +<div class="highlight-python"><pre>%ConvertFromTypeCode + PyObject *l; + + // Create the Python list of the correct length. + if ((l = PyList_New(sipCpp->size())) == NULL) + return NULL; + + // Go through each element in the C++ instance and convert it to a + // wrapped QWidget. + for (int i = 0; i < sipCpp->size(); ++i) + { + QWidget *w = sipCpp->at(i); + PyObject *wobj; + + // Get the Python wrapper for the QWidget instance, creating a new + // one if necessary, and handle any ownership transfer. + if ((wobj = sipConvertFromType(w, sipType_QWidget, sipTransferObj)) == NULL) + { + // There was an error so garbage collect the Python list. + Py_DECREF(l); + return NULL; + } + + // Add the wrapper to the list. + PyList_SET_ITEM(l, i, wobj); + } + + // Return the Python list. + return l; +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%ConvertToSubClassCode"> +<tt class="descname">%ConvertToSubClassCode</tt><a class="headerlink" href="#directive-%ConvertToSubClassCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%ConvertToSubClassCode + <em>code</em> +%End +</pre> +<p>When SIP needs to wrap a C++ class instance it first checks to make sure it +hasn’t already done so. If it has then it just returns a new reference to the +corresponding Python object. Otherwise it creates a new Python object of the +appropriate type. In C++ a function may be defined to return an instance of a +certain class, but can often return a sub-class instead.</p> +<p>This directive is used to specify handwritten code that exploits any available +real-time type information (RTTI) to see if there is a more specific Python +type that can be used when wrapping the C++ instance. The RTTI may be +provided by the compiler or by the C++ instance itself.</p> +<p>The directive is included in the specification of one of the classes that the +handwritten code handles the type conversion for. It doesn’t matter which +one, but a sensible choice would be the one at the root of that class +hierarchy in the module.</p> +<p>Note that if a class hierarchy extends over a number of modules then this +directive should be used in each of those modules to handle the part of the +hierarchy defined in that module. SIP will ensure that the different pieces +of code are called in the right order to determine the most specific Python +type to use.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the C++ class instance.</dd> +<dt>void **sipCppRet</dt> +<dd>When the sub-class is derived from more than one super-class then it is +possible that the C++ address of the instance as the sub-class is +different to that of the super-class. If so, then this must be set to the +C++ address of the instance when cast (usually using <tt class="docutils literal"><span class="pre">static_cast</span></tt>) +from the super-class to the sub-class.</dd> +<dt>const sipTypeDef *sipType</dt> +<dd>The handwritten code must set this to the SIP generated type structure +that corresponds to the class instance. (The type structure for class +<tt class="docutils literal"><span class="pre">Klass</span></tt> is <tt class="docutils literal"><span class="pre">sipType_Klass</span></tt>.) If the RTTI of the class instance isn’t +recognised then <tt class="docutils literal"><span class="pre">sipType</span></tt> must be set to <tt class="docutils literal"><span class="pre">NULL</span></tt>. The code doesn’t +have to recognise the exact class, only the most specific sub-class that +it can.</dd> +<dt>sipWrapperType *sipClass</dt> +<dd><p class="first">The handwritten code must set this to the SIP generated Python type object +that corresponds to the class instance. (The type object for class +<tt class="docutils literal"><span class="pre">Klass</span></tt> is <tt class="docutils literal"><span class="pre">sipClass_Klass</span></tt>.) If the RTTI of the class instance isn’t +recognised then <tt class="docutils literal"><span class="pre">sipClass</span></tt> must be set to <tt class="docutils literal"><span class="pre">NULL</span></tt>. The code doesn’t +have to recognise the exact class, only the most specific sub-class that +it can.</p> +<p class="last">This is deprecated from SIP v4.8. Instead you should use <tt class="docutils literal"><span class="pre">sipType</span></tt>.</p> +</dd> +</dl> +<p>The handwritten code must not explicitly return.</p> +<p>The following example shows the sub-class conversion code for <tt class="docutils literal"><span class="pre">QEvent</span></tt> based +class hierarchy in PyQt:</p> +<div class="highlight-python"><pre>class QEvent +{ +%ConvertToSubClassCode + // QEvent sub-classes provide a unique type ID. + switch (sipCpp->type()) + { + case QEvent::Timer: + sipType = sipType_QTimerEvent; + break; + + case QEvent::KeyPress: + case QEvent::KeyRelease: + sipType = sipType_QKeyEvent; + break; + + // Skip the remaining event types to keep the example short. + + default: + // We don't recognise the type. + sipType = NULL; + } +%End + + // The rest of the class specification. + +};</pre> +</div> +<dl class="directive"> +<dt id="directive-%ConvertToTypeCode"> +<tt class="descname">%ConvertToTypeCode</tt><a class="headerlink" href="#directive-%ConvertToTypeCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%ConvertToTypeCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify the handwritten code that converts a Python +object to a mapped type instance and to handle any ownership transfers. It is +used as part of the <a class="reference internal" href="#directive-%MappedType"><tt class="xref docutils literal"><span class="pre">%MappedType</span></tt></a> directive and as part of a class +specification. The code is also called to determine if the Python object is of +the correct type prior to conversion.</p> +<p>When used as part of a class specification it can automatically convert +additional types of Python object. For example, PyQt uses it in the +specification of the <tt class="docutils literal"><span class="pre">QString</span></tt> class to allow Python string objects and +unicode objects to be used wherever <tt class="docutils literal"><span class="pre">QString</span></tt> instances are expected.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt>int *sipIsErr</dt> +<dd>If this is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the code is being asked to check the type of the +Python object. The check must not have any side effects. Otherwise the +code is being asked to convert the Python object and a non-zero value +should be returned through this pointer if an error occurred during the +conversion.</dd> +<dt>PyObject *sipPy</dt> +<dd>This is the Python object to be converted.</dd> +<dt><em>type</em> **sipCppPtr</dt> +<dd>This is a pointer through which the address of the mapped type instance (or +zero if appropriate) is returned. Its value is undefined if <tt class="docutils literal"><span class="pre">sipIsErr</span></tt> +is <tt class="docutils literal"><span class="pre">NULL</span></tt>.</dd> +<dt>PyObject *sipTransferObj</dt> +<dd>This specifies any desired ownership changes to <em>sipPy</em>. If it is <tt class="docutils literal"><span class="pre">NULL</span></tt> +then the ownership should be left unchanged. If it is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then +ownership should be transferred to Python. Otherwise ownership should be +transferred to C/C++ and <em>sipPy</em> associated with <em>sipTransferObj</em>. The +code can choose to interpret these changes in any way.</dd> +</dl> +<p>The handwritten code must explicitly return an <tt class="docutils literal"><span class="pre">int</span></tt> the meaning of which +depends on the value of <tt class="docutils literal"><span class="pre">sipIsErr</span></tt>.</p> +<p>If <tt class="docutils literal"><span class="pre">sipIsErr</span></tt> is <tt class="docutils literal"><span class="pre">NULL</span></tt> then a non-zero value is returned if the Python +object has a type that can be converted to the mapped type. Otherwise zero is +returned.</p> +<p>If <tt class="docutils literal"><span class="pre">sipIsErr</span></tt> is not <tt class="docutils literal"><span class="pre">NULL</span></tt> then a combination of the following flags is +returned.</p> +<blockquote> +<ul class="simple"> +<li><tt class="xref docutils literal"><span class="pre">SIP_TEMPORARY</span></tt> is set to indicate that the returned instance +is a temporary and should be released to avoid a memory leak.</li> +<li><tt class="xref docutils literal"><span class="pre">SIP_DERIVED_CLASS</span></tt> is set to indicate that the type of the +returned instance is a derived class. See +<a class="reference external" href="c_api.html#ref-derived-classes"><em>Generated Derived Classes</em></a>.</li> +</ul> +</blockquote> +<p>The following example converts a Python list of <tt class="docutils literal"><span class="pre">QPoint</span></tt> instances to a +<tt class="docutils literal"><span class="pre">QList<QPoint></span></tt> instance:</p> +<div class="highlight-python"><pre>%ConvertToTypeCode + // See if we are just being asked to check the type of the Python + // object. + if (!sipIsErr) + { + // Checking whether or not None has been passed instead of a list + // has already been done. + if (!PyList_Check(sipPy)) + return 0; + + // Check the type of each element. We specify SIP_NOT_NONE to + // disallow None because it is a list of QPoint, not of a pointer + // to a QPoint, so None isn't appropriate. + for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) + if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i), + sipType_QPoint, SIP_NOT_NONE)) + return 0; + + // The type is valid. + return 1; + } + + // Create the instance on the heap. + QList<QPoint> *ql = new QList<QPoint>; + + for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) + { + QPoint *qp; + int state; + + // Get the address of the element's C++ instance. Note that, in + // this case, we don't apply any ownership changes to the list + // elements, only to the list itself. + qp = reinterpret_cast<QPoint *>(sipConvertToType( + PyList_GET_ITEM(sipPy, i), + sipType_QPoint, 0, + SIP_NOT_NONE, + &state, sipIsErr)); + + // Deal with any errors. + if (*sipIsErr) + { + sipReleaseType(qp, sipType_QPoint, state); + + // Tidy up. + delete ql; + + // There is no temporary instance. + return 0; + } + + ql->append(*qp); + + // A copy of the QPoint was appended to the list so we no longer + // need it. It may be a temporary instance that should be + // destroyed, or a wrapped instance that should not be destroyed. + // sipReleaseType() will do the right thing. + sipReleaseType(qp, sipType_QPoint, state); + } + + // Return the instance. + *sipCppPtr = ql; + + // The instance should be regarded as temporary (and be destroyed as + // soon as it has been used) unless it has been transferred from + // Python. sipGetState() is a convenience function that implements + // this common transfer behaviour. + return sipGetState(sipTransferObj); +%End</pre> +</div> +<p>When used in a class specification the handwritten code replaces the code that +would normally be automatically generated. This means that the handwritten +code must also handle instances of the class itself and not just the additional +types that are being supported. This should be done by making calls to +<a title="sipCanConvertToType" class="reference external" href="c_api.html#sipCanConvertToType"><tt class="xref docutils literal"><span class="pre">sipCanConvertToType()</span></tt></a> to check the object type and +<a title="sipConvertToType" class="reference external" href="c_api.html#sipConvertToType"><tt class="xref docutils literal"><span class="pre">sipConvertToType()</span></tt></a> to convert the object. The +<a title="SIP_NO_CONVERTORS" class="reference external" href="c_api.html#SIP_NO_CONVERTORS"><tt class="xref docutils literal"><span class="pre">SIP_NO_CONVERTORS</span></tt></a> flag <em>must</em> be passed to both these functions to +prevent recursive calls to the handwritten code.</p> +<dl class="directive"> +<dt id="directive-%Copying"> +<tt class="descname">%Copying</tt><a class="headerlink" href="#directive-%Copying" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%Copying + <em>text</em> +%End +</pre> +<p>This directive is used to specify some arbitrary text that will be included at +the start of all source files generated by SIP. It is normally used to +include copyright and licensing terms.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%Copying +Copyright (c) 2009 Riverbank Computing Limited +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%DefaultEncoding"> +<tt class="descname">%DefaultEncoding</tt><a class="headerlink" href="#directive-%DefaultEncoding" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%DefaultEncoding <em>string</em> +</pre> +<p>This directive is used to specify the default encoding used for <tt class="docutils literal"><span class="pre">char</span></tt>, +<tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span></tt>, <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> values. The encoding can be +either <tt class="docutils literal"><span class="pre">"ASCII"</span></tt>, <tt class="docutils literal"><span class="pre">"Latin-1"</span></tt>, <tt class="docutils literal"><span class="pre">"UTF-8"</span></tt> or <tt class="docutils literal"><span class="pre">"None"</span></tt>. An encoding of +<tt class="docutils literal"><span class="pre">"None"</span></tt> means that the value is unencoded. The default can be overridden +for a particular value using the <a class="reference external" href="annotations.html#aanno-Encoding"><tt class="xref docutils literal"><span class="pre">Encoding</span></tt></a> annotation. If the +directive is not specified then <tt class="docutils literal"><span class="pre">"None"</span></tt> is used.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%DefaultEncoding "Latin-1"</pre> +</div> +<dl class="directive"> +<dt id="directive-%DefaultMetatype"> +<tt class="descname">%DefaultMetatype</tt><a class="headerlink" href="#directive-%DefaultMetatype" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%DefaultMetatype <em>dotted-name</em> +</pre> +<p>This directive is used to specify the Python type that should be used as the +meta-type for any C/C++ data type defined in the same module, and by importing +modules, that doesn’t have an explicit meta-type.</p> +<p>If this is not specified then <tt class="docutils literal"><span class="pre">sip.wrappertype</span></tt> is used.</p> +<p>You can also use the <a class="reference external" href="annotations.html#canno-Metatype"><tt class="xref docutils literal"><span class="pre">Metatype</span></tt></a> class annotation to specify the +meta-type used by a particular C/C++ type.</p> +<p>See the section <a class="reference external" href="using.html#ref-types-metatypes"><em>Types and Meta-types</em></a> for more details.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%DefaultMetatype PyQt4.QtCore.pyqtWrapperType</pre> +</div> +<dl class="directive"> +<dt id="directive-%DefaultSupertype"> +<tt class="descname">%DefaultSupertype</tt><a class="headerlink" href="#directive-%DefaultSupertype" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%DefaultSupertype <em>dotted-name</em> +</pre> +<p>This directive is used to specify the Python type that should be used as the +super-type for any C/C++ data type defined in the same module that doesn’t have +an explicit super-type.</p> +<p>If this is not specified then <tt class="docutils literal"><span class="pre">sip.wrapper</span></tt> is used.</p> +<p>You can also use the <a class="reference external" href="annotations.html#canno-Supertype"><tt class="xref docutils literal"><span class="pre">Supertype</span></tt></a> class annotation to specify the +super-type used by a particular C/C++ type.</p> +<p>See the section <a class="reference external" href="using.html#ref-types-metatypes"><em>Types and Meta-types</em></a> for more details.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%DefaultSupertype sip.simplewrapper</pre> +</div> +<dl class="directive"> +<dt id="directive-%Doc"> +<tt class="descname">%Doc</tt><a class="headerlink" href="#directive-%Doc" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%Doc + <em>text</em> +%End +</pre> +<p>This directive is used to specify some arbitrary text that will be extracted +by SIP when the <tt class="docutils literal"><span class="pre">-d</span></tt> command line option is used. The directive can be +specified any number of times and SIP will concatenate all the separate pieces +of text in the order that it sees them.</p> +<p>Documentation that is specified using this directive is local to the module in +which it appears. It is ignored by modules that <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> it. Use +the <a class="reference internal" href="#directive-%ExportedDoc"><tt class="xref docutils literal"><span class="pre">%ExportedDoc</span></tt></a> directive for documentation that should be +included by all modules that <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> this one.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%Doc +<h1>An Example</h1> +<p> +This fragment of documentation is HTML and is local to the module in +which it is defined. +</p> +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%Docstring"> +<tt class="descname">%Docstring</tt><a class="headerlink" href="#directive-%Docstring" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%Docstring + <em>text</em> +%End +</pre> +<p> +<span class="versionmodified">New in version 4.10.</span></p> +<p>This directive is used to specify explicit docstrings for classes, functions +and methods.</p> +<p>The docstring of a class is made up of the docstring specified for the class +itself, with the docstrings specified for each contructor appended.</p> +<p>The docstring of a function or method is made up of the concatenated docstrings +specified for each of the overloads.</p> +<p>Specifying an explicit docstring will prevent SIP from generating an automatic +docstring that describes the Python signature of a function or method overload. +This means that SIP will generate less informative exceptions (i.e. without a +full signature) when it fails to match a set of arguments to any function or +method overload.</p> +<p>For example:</p> +<div class="highlight-python"><pre>class Klass +{ +%Docstring +This will be at the start of the class's docstring. +%End + +public: + Klass(); +%Docstring +This will be appended to the class's docstring. +%End +};</pre> +</div> +<dl class="directive"> +<dt id="directive-%End"> +<tt class="descname">%End</tt><a class="headerlink" href="#directive-%End" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<p>This isn’t a directive in itself, but is used to terminate a number of +directives that allow a block of handwritten code or text to be specified.</p> +<dl class="directive"> +<dt id="directive-%Exception"> +<tt class="descname">%Exception</tt><a class="headerlink" href="#directive-%Exception" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%Exception <em>name</em> [(<em>base-exception)] +{ + [*header-code</em>] + <em>raise-code</em> +}; +</pre> +<p>This directive is used to define new Python exceptions, or to provide a stub +for existing Python exceptions. It allows handwritten code to be provided +that implements the translation between C++ exceptions and Python exceptions. +The arguments to <tt class="docutils literal"><span class="pre">throw</span> <span class="pre">()</span></tt> specifiers must either be names of classes or the +names of Python exceptions defined by this directive.</p> +<p><em>name</em> is the name of the exception.</p> +<p><em>base-exception</em> is the optional base exception. This may be either one of +the standard Python exceptions or one defined with a previous +<a class="reference internal" href="#directive-%Exception"><tt class="xref docutils literal"><span class="pre">%Exception</span></tt></a> directive.</p> +<p><em>header-code</em> is the optional <a class="reference internal" href="#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a> used to specify any +external interface to the exception being defined.</p> +<p><em>raise-code</em> is the <a class="reference internal" href="#directive-%RaiseCode"><tt class="xref docutils literal"><span class="pre">%RaiseCode</span></tt></a> used to specify the handwritten +code that converts a reference to the C++ exception to the Python exception.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%Exception std::exception(SIP_Exception) /PyName=StdException/ +{ +%TypeHeaderCode +#include <exception> +%End +%RaiseCode + const char *detail = sipExceptionRef.what(); + + SIP_BLOCK_THREADS + PyErr_SetString(sipException_std_exception, detail); + SIP_UNBLOCK_THREADS +%End +};</pre> +</div> +<p>In this example we map the standard C++ exception to a new Python exception. +The new exception is called <tt class="docutils literal"><span class="pre">StdException</span></tt> and is derived from the standard +Python exception <tt class="docutils literal"><span class="pre">Exception</span></tt>.</p> +<p>An exception may be annotated with <a class="reference external" href="annotations.html#xanno-Default"><tt class="xref docutils literal"><span class="pre">Default</span></tt></a> to specify that it should +be caught by default if there is no <tt class="docutils literal"><span class="pre">throw</span></tt> clause.</p> +<dl class="directive"> +<dt id="directive-%ExportedDoc"> +<tt class="descname">%ExportedDoc</tt><a class="headerlink" href="#directive-%ExportedDoc" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%ExportedDoc + <em>text</em> +%End +</pre> +<p>This directive is used to specify some arbitrary text that will be extracted +by SIP when the <tt class="docutils literal"><span class="pre">-d</span></tt> command line option is used. The directive can be +specified any number of times and SIP will concatenate all the separate pieces +of text in the order that it sees them.</p> +<p>Documentation that is specified using this directive will also be included by +modules that <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> it.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%ExportedDoc +========== +An Example +========== + +This fragment of documentation is reStructuredText and will appear in the +module in which it is defined and all modules that %Import it. +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%ExportedHeaderCode"> +<tt class="descname">%ExportedHeaderCode</tt><a class="headerlink" href="#directive-%ExportedHeaderCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%ExportedHeaderCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify handwritten code, typically the declarations +of types, that is placed in a header file that is included by all generated +code for all modules. It should not include function declarations because +Python modules should not explicitly call functions in another Python module.</p> +<p>See also <a class="reference internal" href="#directive-%ModuleCode"><tt class="xref docutils literal"><span class="pre">%ModuleCode</span></tt></a> and <a class="reference internal" href="#directive-%ModuleHeaderCode"><tt class="xref docutils literal"><span class="pre">%ModuleHeaderCode</span></tt></a>.</p> +<dl class="directive"> +<dt id="directive-%Feature"> +<tt class="descname">%Feature</tt><a class="headerlink" href="#directive-%Feature" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%Feature <em>name</em> +</pre> +<p>This directive is used to declare a feature. Features (along with +<a class="reference internal" href="#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a> and <a class="reference internal" href="#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a>) are used by the +<a class="reference internal" href="#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directive to control whether or not parts of a specification +are processed or ignored.</p> +<p>Features are mutually independent of each other - any combination of features +may be enabled or disable. By default all features are enabled. The SIP +<tt class="docutils literal"><span class="pre">-x</span></tt> command line option is used to disable a feature.</p> +<p>If a feature is enabled then SIP will automatically generate a corresponding C +preprocessor symbol for use by handwritten code. The symbol is the name of +the feature prefixed by <tt class="docutils literal"><span class="pre">SIP_FEATURE_</span></tt>.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%Feature FOO_SUPPORT + +%If (FOO_SUPPORT) +void foo(); +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%GCClearCode"> +<tt class="descname">%GCClearCode</tt><a class="headerlink" href="#directive-%GCClearCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%GCClearCode + <em>code</em> +%End +</pre> +<p>Python has a cyclic garbage collector which can identify and release unneeded +objects even when their reference counts are not zero. If a wrapped C +structure or C++ class keeps its own reference to a Python object then, if the +garbage collector is to do its job, it needs to provide some handwritten code +to traverse and potentially clear those embedded references.</p> +<p>See the section <em>Supporting cyclic garbage collection</em> in <a class="reference external" href="http://www.python.org/dev/doc/devel/ext/">Embedding and +Extending the Python Interpreter</a> +for the details.</p> +<p>This directive is used to specify the code that clears any embedded references. +(See <a class="reference internal" href="#directive-%GCTraverseCode"><tt class="xref docutils literal"><span class="pre">%GCTraverseCode</span></tt></a> for specifying the code that traverses any +embedded references.)</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class.</dd> +<dt>int sipRes</dt> +<dd>The handwritten code should set this to the result to be returned.</dd> +</dl> +<p>The following simplified example is taken from PyQt. The <tt class="docutils literal"><span class="pre">QCustomEvent</span></tt> +class allows arbitary data to be attached to the event. In PyQt this data is +always a Python object and so should be handled by the garbage collector:</p> +<div class="highlight-python"><pre>%GCClearCode + PyObject *obj; + + // Get the object. + obj = reinterpret_cast<PyObject *>(sipCpp->data()); + + // Clear the pointer. + sipCpp->setData(0); + + // Clear the reference. + Py_XDECREF(obj); + + // Report no error. + sipRes = 0; +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%GCTraverseCode"> +<tt class="descname">%GCTraverseCode</tt><a class="headerlink" href="#directive-%GCTraverseCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%GCTraverseCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify the code that traverses any embedded +references for Python’s cyclic garbage collector. (See +<a class="reference internal" href="#directive-%GCClearCode"><tt class="xref docutils literal"><span class="pre">%GCClearCode</span></tt></a> for a full explanation.)</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class.</dd> +<dt>visitproc sipVisit</dt> +<dd>This is the visit function provided by the garbage collector.</dd> +<dt>void *sipArg</dt> +<dd>This is the argument to the visit function provided by the garbage +collector.</dd> +<dt>int sipRes</dt> +<dd>The handwritten code should set this to the result to be returned.</dd> +</dl> +<p>The following simplified example is taken from PyQt’s <tt class="docutils literal"><span class="pre">QCustomEvent</span></tt> class:</p> +<div class="highlight-python"><pre>%GCTraverseCode + PyObject *obj; + + // Get the object. + obj = reinterpret_cast<PyObject *>(sipCpp->data()); + + // Call the visit function if there was an object. + if (obj) + sipRes = sipVisit(obj, sipArg); + else + sipRes = 0; +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%GetCode"> +<tt class="descname">%GetCode</tt><a class="headerlink" href="#directive-%GetCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%GetCode + <em>code</em> +%End +</pre> +<p>This directive is used after the declaration of a C++ class variable or C +structure member to specify handwritten code to convert it to a Python object. +It is usually used to handle types that SIP cannot deal with automatically.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class. It is not made available if the +variable being wrapped is a static class variable.</dd> +<dt>PyObject *sipPy</dt> +<dd>The handwritten code must set this to the Python representation of the +class variable or structure member. If there is an error then the code +must raise an exception and set this to <tt class="docutils literal"><span class="pre">NULL</span></tt>.</dd> +<dt>PyObject *sipPyType</dt> +<dd>If the variable being wrapped is a static class variable then this is the +Python type object of the class from which the variable was referenced +(<em>not</em> the class in which it is defined). It may be safely cast to a +PyTypeObject * or a sipWrapperType *.</dd> +</dl> +<p>For example:</p> +<div class="highlight-python"><pre>struct Entity +{ + /* + * In this contrived example the C library we are wrapping actually + * defines this as char buffer[100] which SIP cannot handle + * automatically. + */ + char *buffer; +%GetCode + sipPy = PyString_FromStringAndSize(sipCpp->buffer, 100); +%End +%SetCode + char *ptr; + int length; + + if (PyString_AsStringAndSize(sipPy, &ptr, &length) == -1) + sipErr = 1; + else if (length != 100) + { + /* + * Raise an exception because the length isn't exactly right. + */ + + PyErr_SetString(PyExc_ValueError, "an Entity.buffer must be exactly 100 bytes"); + sipErr = 1; + } + else + memcpy(sipCpp->buffer, ptr, 100); +%End +}</pre> +</div> +<dl class="directive"> +<dt id="directive-%If"> +<tt class="descname">%If</tt><a class="headerlink" href="#directive-%If" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%If (<em>expression</em>) + <em>specification</em> +%End +</pre> +<p>where</p> +<pre class="literal-block"> +<em>expression</em> ::= [<em>ored-qualifiers</em> | <em>range</em>] + +<em>ored-qualifiers</em> ::= [<em>qualifier</em> | <em>qualifier</em> <strong>||</strong> <em>ored-qualifiers</em>] + +<em>qualifier</em> ::= [<strong>!</strong>] [<em>feature</em> | <em>platform</em>] + +<em>range</em> ::= [<em>version</em>] <strong>-</strong> [<em>version</em>] +</pre> +<p>This directive is used in conjunction with features (see +<a class="reference internal" href="#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a>), platforms (see <a class="reference internal" href="#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a>) and versions +(see <a class="reference internal" href="#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a>) to control whether or not parts of a specification +are processed or not.</p> +<p>A <em>range</em> of versions means all versions starting with the lower bound up to +but excluding the upper bound. If the lower bound is omitted then it is +interpreted as being before the earliest version. If the upper bound is +omitted then it is interpreted as being after the latest version.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%Feature SUPPORT_FOO +%Platforms {WIN32_PLATFORM POSIX_PLATFORM MACOS_PLATFORM} +%Timeline {V1_0 V1_1 V2_0 V3_0} + +%If (!SUPPORT_FOO) + // Process this if the SUPPORT_FOO feature is disabled. +%End + +%If (POSIX_PLATFORM || MACOS_PLATFORM) + // Process this if either the POSIX_PLATFORM or MACOS_PLATFORM + // platforms are enabled. +%End + +%If (V1_0 - V2_0) + // Process this if either V1_0 or V1_1 is enabled. +%End + +%If (V2_0 - ) + // Process this if either V2_0 or V3_0 is enabled. +%End + +%If ( - ) + // Always process this. +%End</pre> +</div> +<p>Note that this directive is not implemented as a preprocessor. Only the +following parts of a specification are affected by it:</p> +<blockquote> +<ul class="simple"> +<li><a class="reference internal" href="#directive-%API"><tt class="xref docutils literal"><span class="pre">%API</span></tt></a></li> +<li><tt class="docutils literal"><span class="pre">class</span></tt></li> +<li><a class="reference internal" href="#directive-%ConvertFromTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertFromTypeCode</span></tt></a></li> +<li><a class="reference internal" href="#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a></li> +<li><a class="reference internal" href="#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a></li> +<li><tt class="docutils literal"><span class="pre">enum</span></tt></li> +<li><a class="reference internal" href="#directive-%DefaultEncoding"><tt class="xref docutils literal"><span class="pre">%DefaultEncoding</span></tt></a></li> +<li><a class="reference internal" href="#directive-%DefaultMetatype"><tt class="xref docutils literal"><span class="pre">%DefaultMetatype</span></tt></a></li> +<li><a class="reference internal" href="#directive-%DefaultSupertype"><tt class="xref docutils literal"><span class="pre">%DefaultSupertype</span></tt></a></li> +<li><a class="reference internal" href="#directive-%ExportedHeaderCode"><tt class="xref docutils literal"><span class="pre">%ExportedHeaderCode</span></tt></a></li> +<li>functions</li> +<li><a class="reference internal" href="#directive-%GCClearCode"><tt class="xref docutils literal"><span class="pre">%GCClearCode</span></tt></a></li> +<li><a class="reference internal" href="#directive-%GCTraverseCode"><tt class="xref docutils literal"><span class="pre">%GCTraverseCode</span></tt></a></li> +<li><a class="reference internal" href="#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a></li> +<li><a class="reference internal" href="#directive-%InitialisationCode"><tt class="xref docutils literal"><span class="pre">%InitialisationCode</span></tt></a></li> +<li><a class="reference internal" href="#directive-%MappedType"><tt class="xref docutils literal"><span class="pre">%MappedType</span></tt></a></li> +<li><a class="reference internal" href="#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a></li> +<li><a class="reference internal" href="#directive-%ModuleCode"><tt class="xref docutils literal"><span class="pre">%ModuleCode</span></tt></a></li> +<li><a class="reference internal" href="#directive-%ModuleHeaderCode"><tt class="xref docutils literal"><span class="pre">%ModuleHeaderCode</span></tt></a></li> +<li><tt class="docutils literal"><span class="pre">namespace</span></tt></li> +<li><a class="reference internal" href="#directive-%PostInitialisationCode"><tt class="xref docutils literal"><span class="pre">%PostInitialisationCode</span></tt></a></li> +<li><a class="reference internal" href="#directive-%PreInitialisationCode"><tt class="xref docutils literal"><span class="pre">%PreInitialisationCode</span></tt></a></li> +<li><tt class="docutils literal"><span class="pre">struct</span></tt></li> +<li><tt class="docutils literal"><span class="pre">typedef</span></tt></li> +<li><a class="reference internal" href="#directive-%TypeCode"><tt class="xref docutils literal"><span class="pre">%TypeCode</span></tt></a></li> +<li><a class="reference internal" href="#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a></li> +<li><a class="reference internal" href="#directive-%UnitCode"><tt class="xref docutils literal"><span class="pre">%UnitCode</span></tt></a></li> +<li>variables</li> +<li><a class="reference internal" href="#directive-%VirtualCatcherCode"><tt class="xref docutils literal"><span class="pre">%VirtualCatcherCode</span></tt></a></li> +</ul> +</blockquote> +<p>Also note that the only way to specify the logical and of qualifiers is to use +nested <a class="reference internal" href="#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directives.</p> +<dl class="directive"> +<dt id="directive-%Import"> +<tt class="descname">%Import</tt><a class="headerlink" href="#directive-%Import" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%Import <em>filename</em> +</pre> +<p>This directive is used to import the specification of another module. This is +needed if the current module makes use of any types defined in the imported +module, e.g. as an argument to a function, or to sub-class.</p> +<p>If <em>filename</em> cannot be opened then SIP prepends <em>filename</em> with the name of +the directory containing the current specification file (i.e. the one +containing the <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> directive) and tries again. If this also +fails then SIP prepends <em>filename</em> with each of the directories, in turn, +specified by the <tt class="docutils literal"><span class="pre">-I</span></tt> command line option.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%Import qt/qtmod.sip</pre> +</div> +<dl class="directive"> +<dt id="directive-%Include"> +<tt class="descname">%Include</tt><a class="headerlink" href="#directive-%Include" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%Include <em>filename</em> +</pre> +<p>This directive is used to include contents of another file as part of the +specification of the current module. It is the equivalent of the C +preprocessor’s <tt class="docutils literal"><span class="pre">#include</span></tt> directive and is used to structure a large module +specification into manageable pieces.</p> +<p><a class="reference internal" href="#directive-%Include"><tt class="xref docutils literal"><span class="pre">%Include</span></tt></a> follows the same search process as <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> +when trying to open <em>filename</em>.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%Include qwidget.sip</pre> +</div> +<dl class="directive"> +<dt id="directive-%InitialisationCode"> +<tt class="descname">%InitialisationCode</tt><a class="headerlink" href="#directive-%InitialisationCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%InitialisationCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify handwritten code that is embedded in-line +in the generated module initialisation code after the SIP module has been +imported but before the module itself has been initialised.</p> +<p>It is typically used to call <a title="sipRegisterPyType" class="reference external" href="c_api.html#sipRegisterPyType"><tt class="xref docutils literal"><span class="pre">sipRegisterPyType()</span></tt></a>.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%InitialisationCode + // The code will be executed when the module is first imported, after + // the SIP module has been imported, but before other module-specific + // initialisation has been completed. +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%License"> +<tt class="descname">%License</tt><a class="headerlink" href="#directive-%License" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%License /<em>license-annotations</em>/ +</pre> +<p>This directive is used to specify the contents of an optional license +dictionary. The license dictionary is called <tt class="xref docutils literal"><span class="pre">__license__</span></tt> and is stored +in the module dictionary. The elements of the dictionary are specified using +the <a class="reference external" href="annotations.html#lanno-Licensee"><tt class="xref docutils literal"><span class="pre">Licensee</span></tt></a>, <a class="reference external" href="annotations.html#lanno-Signature"><tt class="xref docutils literal"><span class="pre">Signature</span></tt></a>, <a class="reference external" href="annotations.html#lanno-Timestamp"><tt class="xref docutils literal"><span class="pre">Timestamp</span></tt></a> and <a class="reference external" href="annotations.html#lanno-Type"><tt class="xref docutils literal"><span class="pre">Type</span></tt></a> +annotations. Only the <a class="reference external" href="annotations.html#lanno-Type"><tt class="xref docutils literal"><span class="pre">Type</span></tt></a> annotation is compulsory.</p> +<p>Note that this directive isn’t an attempt to impose any licensing restrictions +on a module. It is simply a method for easily embedding licensing information +in a module so that it is accessible to Python scripts.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%License /Type="GPL"/</pre> +</div> +<dl class="directive"> +<dt id="directive-%MappedType"> +<tt class="descname">%MappedType</tt><a class="headerlink" href="#directive-%MappedType" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +template<<em>type-list</em>> +%MappedType <em>type</em> +{ + [<em>header-code</em>] + [<em>convert-to-code</em>] + [<em>convert-from-code</em>] +}; + +%MappedType <em>type</em> +{ + [<em>header-code</em>] + [<em>convert-to-code</em>] + [<em>convert-from-code</em>] +}; +</pre> +<p>This directive is used to define an automatic mapping between a C or C++ type +and a Python type. It can be used as part of a template, or to map a specific +type.</p> +<p>When used as part of a template <em>type</em> cannot itself refer to a template. Any +occurrences of any of the type names (but not any <tt class="docutils literal"><span class="pre">*</span></tt> or <tt class="docutils literal"><span class="pre">&</span></tt>) in +<em>type-list</em> will be replaced by the actual type names used when the template is +instantiated. Template mapped types are instantiated automatically as required +(unlike template classes which are only instantiated using <tt class="docutils literal"><span class="pre">typedef</span></tt>).</p> +<p>Any explicit mapped type will be used in preference to any template that maps +the same type, ie. a template will not be automatically instantiated if there +is an explicit mapped type.</p> +<p><em>header-code</em> is the <a class="reference internal" href="#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a> used to specify the library +interface to the type being mapped.</p> +<p><em>convert-to-code</em> is the <a class="reference internal" href="#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a> used to specify the +handwritten code that converts a Python object to an instance of the mapped +type.</p> +<p><em>convert-from-code</em> is the <a class="reference internal" href="#directive-%ConvertFromTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertFromTypeCode</span></tt></a> used to specify +the handwritten code that converts an instance of the mapped type to a Python +object.</p> +<p>For example:</p> +<div class="highlight-python"><pre>template<Type *> +%MappedType QList +{ +%TypeHeaderCode +// Include the library interface to the type being mapped. +#include <qlist.h> +%End + +%ConvertToTypeCode + // See if we are just being asked to check the type of the Python + // object. + if (sipIsErr == NULL) + { + // Check it is a list. + if (!PyList_Check(sipPy)) + return 0; + + // Now check each element of the list is of the type we expect. + // The template is for a pointer type so we don't disallow None. + for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) + if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i), + sipType_Type, 0)) + return 0; + + return 1; + } + + // Create the instance on the heap. + QList<Type *> *ql = new QList<Type *>; + + for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) + { + // Use the SIP API to convert the Python object to the + // corresponding C++ instance. Note that we apply any ownership + // transfer to the list itself, not the individual elements. + Type *t = reinterpret_cast<Type *>(sipConvertToType( + PyList_GET_ITEM(sipPy, i), + sipType_Type, 0, 0, 0, + sipIsErr)); + + if (*sipIsErr) + { + // Tidy up. + delete ql; + + // There is nothing on the heap. + return 0; + } + + // Add the pointer to the C++ instance. + ql->append(t); + } + + // Return the instance on the heap. + *sipCppPtr = ql; + + // Apply the normal transfer. + return sipGetState(sipTransferObj); +%End + +%ConvertFromTypeCode + PyObject *l; + + // Create the Python list of the correct length. + if ((l = PyList_New(sipCpp->size())) == NULL) + return NULL; + + // Go through each element in the C++ instance and convert it to the + // corresponding Python object. + for (int i = 0; i < sipCpp->size(); ++i) + { + Type *t = sipCpp->at(i); + PyObject *tobj; + + if ((tobj = sipConvertFromType(t, sipType_Type, sipTransferObj)) == NULL) + { + // There was an error so garbage collect the Python list. + Py_DECREF(l); + return NULL; + } + + PyList_SET_ITEM(l, i, tobj); + } + + // Return the Python list. + return l; +%End +}</pre> +</div> +<p>Using this we can use, for example, <tt class="docutils literal"><span class="pre">QList<QObject</span> <span class="pre">*></span></tt> throughout the +module’s specification files (and in any module that imports this one). The +generated code will automatically map this to and from a Python list of QObject +instances when appropriate.</p> +<dl class="directive"> +<dt id="directive-%MethodCode"> +<tt class="descname">%MethodCode</tt><a class="headerlink" href="#directive-%MethodCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%MethodCode + <em>code</em> +%End +</pre> +<p>This directive is used as part of the specification of a global function, class +method, operator, constructor or destructor to specify handwritten code that +replaces the normally generated call to the function being wrapped. It is +usually used to handle argument types and results that SIP cannot deal with +automatically.</p> +<p>Normally the specified code is embedded in-line after the function’s arguments +have been successfully converted from Python objects to their C or C++ +equivalents. In this case the specified code must not include any <tt class="docutils literal"><span class="pre">return</span></tt> +statements.</p> +<p>However if the <a class="reference external" href="annotations.html#fanno-NoArgParser"><tt class="xref docutils literal"><span class="pre">NoArgParser</span></tt></a> annotation has been used then the specified +code is also responsible for parsing the arguments. No other code is generated +by SIP and the specified code must include a <tt class="docutils literal"><span class="pre">return</span></tt> statement.</p> +<p>In the context of a destructor the specified code is embedded in-line in the +Python type’s deallocation function. Unlike other contexts it supplements +rather than replaces the normally generated code, so it must not include code +to return the C structure or C++ class instance to the heap. The code is only +called if ownership of the structure or class is with Python.</p> +<p>The specified code must also handle the Python Global Interpreter Lock (GIL). +If compatibility with SIP v3.x is required then the GIL must be released +immediately before the C++ call and reacquired immediately afterwards as shown +in this example fragment:</p> +<div class="highlight-python"><pre>Py_BEGIN_ALLOW_THREADS +sipCpp->foo(); +Py_END_ALLOW_THREADS</pre> +</div> +<p>If compatibility with SIP v3.x is not required then this is optional but +should be done if the C++ function might block the current thread or take a +significant amount of time to execute. (See <a class="reference external" href="using.html#ref-gil"><em>The Python Global Interpreter Lock</em></a> and the +<a class="reference external" href="annotations.html#fanno-ReleaseGIL"><tt class="xref docutils literal"><span class="pre">ReleaseGIL</span></tt></a> and <a class="reference external" href="annotations.html#fanno-HoldGIL"><tt class="xref docutils literal"><span class="pre">HoldGIL</span></tt></a> annotations.)</p> +<p>If the <a class="reference external" href="annotations.html#fanno-NoArgParser"><tt class="xref docutils literal"><span class="pre">NoArgParser</span></tt></a> annotation has not been used then the following +variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> a0</dt> +<dd><p class="first">There is a variable for each argument of the Python signature (excluding +any <tt class="docutils literal"><span class="pre">self</span></tt> argument) named <tt class="docutils literal"><span class="pre">a0</span></tt>, <tt class="docutils literal"><span class="pre">a1</span></tt>, etc. The <em>type</em> of the +variable is the same as the type defined in the specification with the +following exceptions:</p> +<ul class="simple"> +<li>if the argument is only used to return a value (e.g. it is an <tt class="docutils literal"><span class="pre">int</span> <span class="pre">*</span></tt> +without an <a class="reference external" href="annotations.html#aanno-In"><tt class="xref docutils literal"><span class="pre">In</span></tt></a> annotation) then the type has one less level of +indirection (e.g. it will be an <tt class="docutils literal"><span class="pre">int</span></tt>)</li> +<li>if the argument is a structure or class (or a reference or a pointer to a +structure or class) then <em>type</em> will always be a pointer to the structure +or class.</li> +</ul> +<p class="last">Note that handwritten code for destructors never has any arguments.</p> +</dd> +<dt>PyObject *a0Wrapper</dt> +<dd>This variable is made available only if the <a class="reference external" href="annotations.html#aanno-GetWrapper"><tt class="xref docutils literal"><span class="pre">GetWrapper</span></tt></a> annotation +is specified for the corresponding argument. The variable is a pointer to +the Python object that wraps the argument.</dd> +<dt><em>type</em> *sipCpp</dt> +<dd><p class="first">If the directive is used in the context of a class constructor then this +must be set by the handwritten code to the constructed instance. If it is +set to <tt class="docutils literal"><span class="pre">0</span></tt> and no Python exception is raised then SIP will continue to +try other Python signatures.</p> +<p>If the directive is used in the context of a method (but not the standard +binary operator methods, e.g. <tt class="xref docutils literal"><span class="pre">__add__()</span></tt>) or a destructor then this is +a pointer to the C structure or C++ class instance.</p> +<p>Its <em>type</em> is a pointer to the structure or class.</p> +<p class="last">Standard binary operator methods follow the same convention as global +functions and instead define two arguments called <tt class="docutils literal"><span class="pre">a0</span></tt> and <tt class="docutils literal"><span class="pre">a1</span></tt>.</p> +</dd> +<dt>sipErrorState sipError</dt> +<dd><p class="first">The handwritten code should set this to either <tt class="docutils literal"><span class="pre">sipErrorContinue</span></tt> or +<tt class="docutils literal"><span class="pre">sipErrorFail</span></tt>, and raise an appropriate Python exception, if an error +is detected. Its initial value will be <tt class="docutils literal"><span class="pre">sipErrorNone</span></tt>.</p> +<p>When <tt class="docutils literal"><span class="pre">sipErrorContinue</span></tt> is used, SIP will remember the exception as the +reason why the particular overloaded callable could not be invoked. It +will then continue to try the next overloaded callable. It is typically +used by code that needs to do additional type checking of the callable’s +arguments.</p> +<p>When <tt class="docutils literal"><span class="pre">sipErrorFail1</span></tt> is used, SIP will report the exception immediately +and will not attempt to invoke other overloaded callables.</p> +<p class="last"><tt class="docutils literal"><span class="pre">sipError</span></tt> is not provided for destructors.</p> +</dd> +<dt>int sipIsErr</dt> +<dd><p class="first">The handwritten code should set this to a non-zero value, and raise an +appropriate Python exception, if an error is detected. This is the +equivalent of setting <tt class="docutils literal"><span class="pre">sipError</span></tt> to <tt class="docutils literal"><span class="pre">sipErrorFail</span></tt>. Its initial value +will be <tt class="docutils literal"><span class="pre">0</span></tt>.</p> +<p class="last"><tt class="docutils literal"><span class="pre">sipIsErr</span></tt> is not provided for destructors.</p> +</dd> +<dt><em>type</em> sipRes</dt> +<dd><p class="first">The handwritten code should set this to the result to be returned. The +<em>type</em> of the variable is the same as the type defined in the Python +signature in the specification with the following exception:</p> +<ul class="simple"> +<li>if the argument is a structure or class (or a reference or a pointer to a +structure or class) then <em>type</em> will always be a pointer to the structure +or class.</li> +</ul> +<p class="last"><tt class="docutils literal"><span class="pre">sipRes</span></tt> is not provided for inplace operators (e.g. <tt class="docutils literal"><span class="pre">+=</span></tt> or +<tt class="xref docutils literal"><span class="pre">__imul__()</span></tt>) as their results are handled automatically, nor for class +constructors or destructors.</p> +</dd> +<dt>PyObject *sipSelf</dt> +<dd>If the directive is used in the context of a class constructor, destructor +or method then this is the Python object that wraps the structure or class +instance, i.e. <tt class="docutils literal"><span class="pre">self</span></tt>.</dd> +<dt>bool sipSelfWasArg</dt> +<dd><p class="first">This is only made available for non-abstract, virtual methods. It is set +if <tt class="docutils literal"><span class="pre">self</span></tt> was explicitly passed as the first argument of the method +rather than being bound to the method. In other words, the call was:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="n">Klass</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span> +</pre></div> +</div> +<p>rather than:</p> +<div class="last highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="o">...</span><span class="p">)</span> +</pre></div> +</div> +</dd> +</dl> +<p>If the <a class="reference external" href="annotations.html#fanno-NoArgParser"><tt class="xref docutils literal"><span class="pre">NoArgParser</span></tt></a> annotation has been used then only the following +variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt>PyObject *sipArgs</dt> +<dd>This is the tuple of arguments.</dd> +<dt>PyObject *sipKwds</dt> +<dd>This is the dictionary of keyword arguments.</dd> +</dl> +<p>The following is a complete example:</p> +<div class="highlight-python"><pre>class Klass +{ +public: + virtual int foo(SIP_PYTUPLE); +%MethodCode + // The C++ API takes a 2 element array of integers but passing a + // two element tuple is more Pythonic. + + int iarr[2]; + + if (PyArg_ParseTuple(a0, "ii", &iarr[0], &iarr[1])) + { + Py_BEGIN_ALLOW_THREADS + sipRes = sipSelfWasArg ? sipCpp->Klass::foo(iarr) + : sipCpp->foo(iarr); + Py_END_ALLOW_THREADS + } + else + { + // PyArg_ParseTuple() will have raised the exception. + sipIsErr = 1; + } +%End +};</pre> +</div> +<p>As the example is a virtual method <a class="footnote-reference" href="#id2" id="id1">[1]</a>, note the use of <tt class="docutils literal"><span class="pre">sipSelfWasArg</span></tt> to +determine exactly which implementation of <tt class="docutils literal"><span class="pre">foo()</span></tt> to call.</p> +<p>If a method is in the <tt class="docutils literal"><span class="pre">protected</span></tt> section of a C++ class then SIP generates +helpers that provide access to method. However, these are not available if +the Python module is being built with <tt class="docutils literal"><span class="pre">protected</span></tt> redefined as <tt class="docutils literal"><span class="pre">public</span></tt>.</p> +<p>The following pattern should be used to cover all possibilities:</p> +<div class="highlight-python"><pre>#if defined(SIP_PROTECTED_IS_PUBLIC) + sipRes = sipSelfWasArg ? sipCpp->Klass::foo(iarr) + : sipCpp->foo(iarr); +#else + sipRes = sipCpp->sipProtectVirt_foo(sipSelfWasArg, iarr); +#endif</pre> +</div> +<p>If a method is in the <tt class="docutils literal"><span class="pre">protected</span></tt> section of a C++ class but is not virtual +then the pattern should instead be:</p> +<div class="highlight-python"><pre>#if defined(SIP_PROTECTED_IS_PUBLIC) + sipRes = sipCpp->foo(iarr); +#else + sipRes = sipCpp->sipProtect_foo(iarr); +#endif</pre> +</div> +<table class="docutils footnote" frame="void" id="id2" 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>See <a class="reference internal" href="#directive-%VirtualCatcherCode"><tt class="xref docutils literal"><span class="pre">%VirtualCatcherCode</span></tt></a> for a description of how SIP +generated code handles the reimplementation of C++ virtual methods in +Python.</td></tr> +</tbody> +</table> +<dl class="directive"> +<dt id="directive-%Module"> +<tt class="descname">%Module</tt><a class="headerlink" href="#directive-%Module" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%Module <em>name</em> [<em>version</em>] +</pre> +<p>This directive is used to identify that the library being wrapped is a C++ +library and to define the name of the module and it’s optional version number.</p> +<p>The name may contain periods to specify that the module is part of a Python +package.</p> +<p>The optional version number is useful if you (or others) might create other +modules that build on this module, i.e. if another module might +<a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> this module. Under the covers, a module exports an API +that is used by modules that <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> it and the API is given a +version number. A module built on that module knows the version number of the +API that it is expecting. If, when the modules are imported at run-time, the +version numbers do not match then a Python exception is raised. The dependent +module must then be re-built using the correct specification files for the base +module.</p> +<p>The version number should be incremented whenever a module is changed. Some +changes don’t affect the exported API, but it is good practice to change the +version number anyway.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%Module qt 5</pre> +</div> +<dl class="directive"> +<dt id="directive-%ModuleCode"> +<tt class="descname">%ModuleCode</tt><a class="headerlink" href="#directive-%ModuleCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%ModuleCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify handwritten code, typically the +implementations of utility functions, that can be called by other handwritten +code in the module.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%ModuleCode +// Print an object on stderr for debugging purposes. +void dump_object(PyObject *o) +{ + PyObject_Print(o, stderr, 0); + fprintf(stderr, "\n"); +} +%End</pre> +</div> +<p>See also <a class="reference internal" href="#directive-%ExportedHeaderCode"><tt class="xref docutils literal"><span class="pre">%ExportedHeaderCode</span></tt></a> and <a class="reference internal" href="#directive-%ModuleHeaderCode"><tt class="xref docutils literal"><span class="pre">%ModuleHeaderCode</span></tt></a>.</p> +<dl class="directive"> +<dt id="directive-%ModuleHeaderCode"> +<tt class="descname">%ModuleHeaderCode</tt><a class="headerlink" href="#directive-%ModuleHeaderCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%ModuleHeaderCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify handwritten code, typically the declarations +of utility functions, that is placed in a header file that is included by all +generated code for the same module.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%ModuleHeaderCode +void dump_object(PyObject *o); +%End</pre> +</div> +<p>See also <a class="reference internal" href="#directive-%ExportedHeaderCode"><tt class="xref docutils literal"><span class="pre">%ExportedHeaderCode</span></tt></a> and <a class="reference internal" href="#directive-%ModuleCode"><tt class="xref docutils literal"><span class="pre">%ModuleCode</span></tt></a>.</p> +<dl class="directive"> +<dt id="directive-%OptionalInclude"> +<tt class="descname">%OptionalInclude</tt><a class="headerlink" href="#directive-%OptionalInclude" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%OptionalInclude <em>filename</em> +</pre> +<p>This directive is identical to the <a class="reference internal" href="#directive-%Include"><tt class="xref docutils literal"><span class="pre">%Include</span></tt></a> directive except that +SIP silently continues processing if <em>filename</em> could not be opened.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%OptionalInclude license.sip</pre> +</div> +<dl class="directive"> +<dt id="directive-%PickleCode"> +<tt class="descname">%PickleCode</tt><a class="headerlink" href="#directive-%PickleCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%PickleCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify handwritten code to pickle a C structure or +C++ class instance.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class.</dd> +<dt>PyObject *sipRes</dt> +<dd>The handwritten code must set this to a tuple of the arguments that will +be passed to the type’s __init__() method when the structure or class +instance is unpickled. If there is an error then the code must raise an +exception and set this to <tt class="docutils literal"><span class="pre">NULL</span></tt>.</dd> +</dl> +<p>For example:</p> +<div class="highlight-python"><pre>class Point +{ + Point(int x, y); + + int x() const; + int y() const; + +%PickleCode + sipRes = Py_BuildValue("ii", sipCpp->x(), sipCpp->y()); +%End +}</pre> +</div> +<p>Note that SIP works around the Python limitation that prevents nested types +being pickled.</p> +<p>Both named and unnamed enums can be pickled automatically without providing any +handwritten code.</p> +<dl class="directive"> +<dt id="directive-%Platforms"> +<tt class="descname">%Platforms</tt><a class="headerlink" href="#directive-%Platforms" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%Platforms {<em>name</em> <em>name</em> ...} +</pre> +<p>This directive is used to declare a set of platforms. Platforms (along with +<a class="reference internal" href="#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> and <a class="reference internal" href="#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a>) are used by the +<a class="reference internal" href="#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directive to control whether or not parts of a specification +are processed or ignored.</p> +<p>Platforms are mutually exclusive - only one platform can be enabled at a time. +By default all platforms are disabled. The SIP <tt class="docutils literal"><span class="pre">-t</span></tt> command line option is +used to enable a platform.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%Platforms {WIN32_PLATFORM POSIX_PLATFORM MACOS_PLATFORM} + +%If (WIN32_PLATFORM) +void undocumented(); +%End + +%If (POSIX_PLATFORM) +void documented(); +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%PostInitialisationCode"> +<tt class="descname">%PostInitialisationCode</tt><a class="headerlink" href="#directive-%PostInitialisationCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%PostInitialisationCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify handwritten code that is embedded in-line +at the very end of the generated module initialisation code.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt>PyObject *sipModule</dt> +<dd>This is the module object returned by <tt class="docutils literal"><span class="pre">Py_InitModule()</span></tt>.</dd> +<dt>PyObject *sipModuleDict</dt> +<dd>This is the module’s dictionary object returned by <tt class="docutils literal"><span class="pre">Py_ModuleGetDict()</span></tt>.</dd> +</dl> +<p>For example:</p> +<div class="highlight-python"><pre>%PostInitialisationCode + // The code will be executed when the module is first imported and + // after all other initialisation has been completed. +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%PreInitialisationCode"> +<tt class="descname">%PreInitialisationCode</tt><a class="headerlink" href="#directive-%PreInitialisationCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%PreInitialisationCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify handwritten code that is embedded in-line +at the very start of the generated module initialisation code.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%PreInitialisationCode + // The code will be executed when the module is first imported and + // before other initialisation has been completed. +%End</pre> +</div> +<dl class="directive"> +<dt id="directive-%RaiseCode"> +<tt class="descname">%RaiseCode</tt><a class="headerlink" href="#directive-%RaiseCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%RaiseCode + <em>code</em> +%End +</pre> +<p>This directive is used as part of the definition of an exception using the +<a class="reference internal" href="#directive-%Exception"><tt class="xref docutils literal"><span class="pre">%Exception</span></tt></a> directive to specify handwritten code that raises a +Python exception when a C++ exception has been caught. The code is embedded +in-line as the body of a C++ <tt class="docutils literal"><span class="pre">catch</span> <span class="pre">()</span></tt> clause.</p> +<p>The specified code must handle the Python Global Interpreter Lock (GIL) if +necessary. The GIL must be acquired before any calls to the Python API and +released after the last call as shown in this example fragment:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="n">SIP_BLOCK_THREADS</span> +<span class="n">PyErr_SetNone</span><span class="p">(</span><span class="n">PyErr_Exception</span><span class="p">);</span> +<span class="n">SIP_UNBLOCK_THREADS</span> +</pre></div> +</div> +<p>Finally, the specified code must not include any <tt class="docutils literal"><span class="pre">return</span></tt> statements.</p> +<p>The following variable is made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> &sipExceptionRef</dt> +<dd>This is a reference to the caught C++ exception. The <em>type</em> of the +reference is the same as the type defined in the <tt class="docutils literal"><span class="pre">throw</span> <span class="pre">()</span></tt> specifier.</dd> +</dl> +<p>See the <a class="reference internal" href="#directive-%Exception"><tt class="xref docutils literal"><span class="pre">%Exception</span></tt></a> directive for an example.</p> +<dl class="directive"> +<dt id="directive-%SetCode"> +<tt class="descname">%SetCode</tt><a class="headerlink" href="#directive-%SetCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%SetCode + <em>code</em> +%End +</pre> +<p>This directive is used after the declaration of a C++ class variable or C +structure member to specify handwritten code to convert it from a Python +object. It is usually used to handle types that SIP cannot deal with +automatically.</p> +<p>The following variables are made available to the handwritten code:</p> +<dl class="docutils"> +<dt><em>type</em> *sipCpp</dt> +<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a +pointer to the structure or class. It is not made available if the +variable being wrapped is a static class variable.</dd> +<dt>int sipErr</dt> +<dd>If the conversion failed then the handwritten code should raise a Python +exception and set this to a non-zero value. Its initial value will be +automatically set to zero.</dd> +<dt>PyObject *sipPy</dt> +<dd>This is the Python object that the handwritten code should convert.</dd> +<dt>PyObject *sipPyType</dt> +<dd>If the variable being wrapped is a static class variable then this is the +Python type object of the class from which the variable was referenced +(<em>not</em> the class in which it is defined). It may be safely cast to a +PyTypeObject * or a sipWrapperType *.</dd> +</dl> +<p>See the <a class="reference internal" href="#directive-%GetCode"><tt class="xref docutils literal"><span class="pre">%GetCode</span></tt></a> directive for an example.</p> +<dl class="directive"> +<dt id="directive-%Timeline"> +<tt class="descname">%Timeline</tt><a class="headerlink" href="#directive-%Timeline" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%Timeline {<em>name</em> <em>name</em> ...} +</pre> +<p>This directive is used to declare a set of versions released over a period of +time. Versions (along with <a class="reference internal" href="#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> and <a class="reference internal" href="#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a>) +are used by the <a class="reference internal" href="#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directive to control whether or not parts of a +specification are processed or ignored.</p> +<p>Versions are mutually exclusive - only one version can be enabled at a time. +By default all versions are disabled. The SIP <tt class="docutils literal"><span class="pre">-t</span></tt> command line option is +used to enable a version.</p> +<p>For example:</p> +<div class="highlight-python"><pre>%Timeline {V1_0 V1_1 V2_0 V3_0} + +%If (V1_0 - V2_0) +void foo(); +%End + +%If (V2_0 -) +void foo(int = 0); +%End</pre> +</div> +<p><a class="reference internal" href="#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a> can be used any number of times in a module to allow +multiple libraries to be wrapped in the same module.</p> +<dl class="directive"> +<dt id="directive-%TypeCode"> +<tt class="descname">%TypeCode</tt><a class="headerlink" href="#directive-%TypeCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%TypeCode + <em>code</em> +%End +</pre> +<p>This directive is used as part of the specification of a C structure or a C++ +class to specify handwritten code, typically the implementations of utility +functions, that can be called by other handwritten code in the structure or +class.</p> +<p>For example:</p> +<div class="highlight-python"><pre>class Klass +{ +%TypeCode +// Print an instance on stderr for debugging purposes. +static void dump_klass(const Klass *k) +{ + fprintf(stderr,"Klass %s at %p\n", k->name(), k); +} +%End + + // The rest of the class specification. + +};</pre> +</div> +<p>Because the scope of the code is normally within the generated file that +implements the type, any utility functions would normally be declared +<tt class="docutils literal"><span class="pre">static</span></tt>. However a naming convention should still be adopted to prevent +clashes of function names within a module in case the SIP <tt class="docutils literal"><span class="pre">-j</span></tt> command line +option is used.</p> +<dl class="directive"> +<dt id="directive-%TypeHeaderCode"> +<tt class="descname">%TypeHeaderCode</tt><a class="headerlink" href="#directive-%TypeHeaderCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%TypeHeaderCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify handwritten code that defines the interface +to a C or C++ type being wrapped, either a structure, a class, or a template. +It is used within a class definition or a <a class="reference internal" href="#directive-%MappedType"><tt class="xref docutils literal"><span class="pre">%MappedType</span></tt></a> directive.</p> +<p>Normally <em>code</em> will be a pre-processor <tt class="docutils literal"><span class="pre">#include</span></tt> statement.</p> +<p>For example:</p> +<div class="highlight-python"><pre>// Wrap the Klass class. +class Klass +{ +%TypeHeaderCode +#include <klass.h> +%End + + // The rest of the class specification. +};</pre> +</div> +<dl class="directive"> +<dt id="directive-%UnitCode"> +<tt class="descname">%UnitCode</tt><a class="headerlink" href="#directive-%UnitCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%UnitCode + <em>code</em> +%End +</pre> +<p>This directive is used to specify handwritten code that it included at the very +start of a generated compilation unit (ie. C or C++ source file). It is +typically used to <tt class="docutils literal"><span class="pre">#include</span></tt> a C++ precompiled header file.</p> +<dl class="directive"> +<dt id="directive-%VirtualCatcherCode"> +<tt class="descname">%VirtualCatcherCode</tt><a class="headerlink" href="#directive-%VirtualCatcherCode" title="Permalink to this definition">¶</a></dt> +<dd></dd></dl> + +<pre class="literal-block"> +%VirtualCatcherCode + <em>code</em> +%End +</pre> +<p>For most classes there are corresponding <a class="reference external" href="c_api.html#ref-derived-classes"><em>generated derived classes</em></a> that contain reimplementations of the class’s virtual +methods. These methods (which SIP calls catchers) determine if there is a +corresponding Python reimplementation and call it if so. If there is no Python +reimplementation then the method in the original class is called instead.</p> +<p>This directive is used to specify handwritten code that replaces the normally +generated call to the Python reimplementation and the handling of any returned +results. It is usually used to handle argument types and results that SIP +cannot deal with automatically.</p> +<p>This directive can also be used in the context of a class destructor to +specify handwritten code that is embedded in-line in the internal derived +class’s destructor.</p> +<p>In the context of a method the Python Global Interpreter Lock (GIL) is +automatically acquired before the specified code is executed and automatically +released afterwards.</p> +<p>In the context of a destructor the specified code must handle the GIL. The +GIL must be acquired before any calls to the Python API and released after the +last call as shown in this example fragment:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="n">SIP_BLOCK_THREADS</span> +<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">obj</span><span class="p">);</span> +<span class="n">SIP_UNBLOCK_THREADS</span> +</pre></div> +</div> +<p>The following variables are made available to the handwritten code in the +context of a method:</p> +<dl class="docutils"> +<dt><em>type</em> a0</dt> +<dd>There is a variable for each argument of the C++ signature named <tt class="docutils literal"><span class="pre">a0</span></tt>, +<tt class="docutils literal"><span class="pre">a1</span></tt>, etc. The <em>type</em> of the variable is the same as the type defined in +the specification.</dd> +<dt>int a0Key</dt> +<dd>There is a variable for each argument of the C++ signature that has a type +where it is important to ensure that the corresponding Python object is not +garbage collected too soon. This only applies to output arguments that +return <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated strings. The variable would normally be passed +to <a title="sipParseResult" class="reference external" href="c_api.html#sipParseResult"><tt class="xref docutils literal"><span class="pre">sipParseResult()</span></tt></a> using either the <tt class="docutils literal"><span class="pre">A</span></tt> or <tt class="docutils literal"><span class="pre">B</span></tt> format +characters.</dd> +<dt>int sipIsErr</dt> +<dd>The handwritten code should set this to a non-zero value, and raise an +appropriate Python exception, if an error is detected.</dd> +<dt>PyObject *sipMethod</dt> +<dd>This object is the Python reimplementation of the virtual C++ method. It +is normally passed to <a title="sipCallMethod" class="reference external" href="c_api.html#sipCallMethod"><tt class="xref docutils literal"><span class="pre">sipCallMethod()</span></tt></a>.</dd> +<dt><em>type</em> sipRes</dt> +<dd>The handwritten code should set this to the result to be returned. The +<em>type</em> of the variable is the same as the type defined in the C++ signature +in the specification.</dd> +<dt>int sipResKey</dt> +<dd>This variable is only made available if the result has a type where it is +important to ensure that the corresponding Python object is not garbage +collected too soon. This only applies to <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated strings. The +variable would normally be passed to <a title="sipParseResult" class="reference external" href="c_api.html#sipParseResult"><tt class="xref docutils literal"><span class="pre">sipParseResult()</span></tt></a> using either +the <tt class="docutils literal"><span class="pre">A</span></tt> or <tt class="docutils literal"><span class="pre">B</span></tt> format characters.</dd> +<dt>sipSimpleWrapper *sipPySelf</dt> +<dd>This variable is only made available if either the <tt class="docutils literal"><span class="pre">a0Key</span></tt> or +<tt class="docutils literal"><span class="pre">sipResKey</span></tt> are made available. It defines the context within which keys +are unique. The variable would normally be passed to +<a title="sipParseResult" class="reference external" href="c_api.html#sipParseResult"><tt class="xref docutils literal"><span class="pre">sipParseResult()</span></tt></a> using the <tt class="docutils literal"><span class="pre">S</span></tt> format character.</dd> +</dl> +<p>No variables are made available in the context of a destructor.</p> +<p>For example:</p> +<div class="highlight-python"><pre>class Klass +{ +public: + virtual int foo(SIP_PYTUPLE) [int (int *)]; +%MethodCode + // The C++ API takes a 2 element array of integers but passing a + // two element tuple is more Pythonic. + + int iarr[2]; + + if (PyArg_ParseTuple(a0, "ii", &iarr[0], &iarr[1])) + { + Py_BEGIN_ALLOW_THREADS + sipRes = sipCpp->Klass::foo(iarr); + Py_END_ALLOW_THREADS + } + else + { + // PyArg_ParseTuple() will have raised the exception. + sipIsErr = 1; + } +%End +%VirtualCatcherCode + // Convert the 2 element array of integers to the two element + // tuple. + + PyObject *result; + + result = sipCallMethod(&sipIsErr, sipMethod, "ii", a0[0], a0[1]); + + if (result != NULL) + { + // Convert the result to the C++ type. + sipParseResult(&sipIsErr, sipMethod, result, "i", &sipRes); + + Py_DECREF(result); + } +%End +};</pre> +</div> +</div> + + + </div> + </div> + </div> + <div class="sphinxsidebar"> + <div class="sphinxsidebarwrapper"> + <h4>Previous topic</h4> + <p class="topless"><a href="specification_files.html" + title="previous chapter">SIP Specification Files</a></p> + <h4>Next topic</h4> + <p class="topless"><a href="annotations.html" + title="next chapter">Annotations</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="annotations.html" title="Annotations" + >next</a> |</li> + <li class="right" > + <a href="specification_files.html" title="SIP Specification Files" + >previous</a> |</li> + <li><a href="index.html">SIP 4.10.5 Reference Guide</a> »</li> + </ul> + </div> + <div class="footer"> + © Copyright 2010 Riverbank Computing Limited. + Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4. + </div> + </body> +</html>
\ No newline at end of file |