<liclass="toctree-l4"><aclass="reference internal"href="../UsersGuide/Installation.html#building-the-devel-branch">Building the Devel Branch</a></li>
<liclass="toctree-l4"><aclass="reference internal"href="../UsersGuide/Installation.html#additionnal-requirement-under-macos">Additionnal Requirement under <spanclass="sc">MacOS</span></a></li>
<liclass="toctree-l3"><aclass="reference internal"href="../UsersGuide/Installation.html#hooking-up-into-alliance">Hooking up into <spanclass="sc">Alliance</span></a></li>
<liclass="toctree-l3"><aclass="reference internal"href="../UsersGuide/Installation.html#setting-up-the-environment-coriolisenv-py">Setting up the Environment (coriolisEnv.py)</a></li>
</ul>
</li>
<liclass="toctree-l2"><aclass="reference internal"href="../UsersGuide/Configuration.html">Coriolis Configuration & Initialisation</a><ul>
<liclass="toctree-l3"><aclass="reference internal"href="../UsersGuide/Configuration.html#hacking-the-configuration-files">Hacking the Configuration Files</a></li>
</ul>
</li>
<liclass="toctree-l2"><aclass="reference internal"href="../UsersGuide/ViewerTools.html">CGT - The Graphical Interface</a><ul>
<liclass="toctree-l3"><aclass="reference internal"href="../UsersGuide/ViewerTools.html#viewer-tools">Viewer & Tools</a><ul>
<liclass="toctree-l4"><aclass="reference internal"href="../UsersGuide/ViewerTools.html#synthetizing-and-loading-a-design">Synthetizing and loading a design</a></li>
<liclass="toctree-l4"><aclass="reference internal"href="../UsersGuide/ViewerTools.html#executing-python-scripts-in-cgt">Executing Python Scripts in Cgt</a></li>
<liclass="toctree-l4"><aclass="reference internal"href="../UsersGuide/ViewerTools.html#printing-snapshots">Printing & Snapshots</a></li>
<liclass="toctree-l4"><aclass="reference internal"href="../UsersGuide/ViewerTools.html#memento-of-shortcuts-in-graphic-mode">Memento of Shortcuts in Graphic Mode</a></li>
<liclass="toctree-l4"><aclass="reference internal"href="../UsersGuide/ViewerTools.html#cgt-command-line-options">Cgt Command Line Options</a></li>
<h1>3. Case 1 - DBo Derived, Standalone<aclass="headerlink"href="#case-1-dbo-derived-standalone"title="Permalink to this headline">¶</a></h1>
<p>As example, we take <ttclass="docutils literal"><spanclass="pre">Library</span></tt>. This a <ttclass="docutils literal"><spanclass="pre">DBo</span></tt> derived class, but we
choose not to export the parent classes. From Python, it will appear
<spanid="id1"></span><spanid="id2"></span><h2>3.1 Class Associated Header File<aclass="headerlink"href="#class-associated-header-file"title="Permalink to this headline">¶</a></h2>
<p>Here is the typical content of a header file (for <ttclass="docutils literal"><spanclass="pre">PyLibrary</span></tt>):</p>
<li><pclass="first">It must have, <em>as the first include</em><ttclass="docutils literal"><spanclass="pre">PyHurricane.h</span></tt>, which provides
the complete bunch of macros needed to build the module. Then the include
of the C++ class we want to wrap (<ttclass="docutils literal"><spanclass="pre">Library.h</span></tt>).</p>
</li>
<li><pclass="first">As Python is written in C, all the wrapper code has to be but inside
an <ttclass="docutils literal"><spanclass="pre">extern</span><spanclass="pre">"C"</span></tt> namespace.</p>
</li>
<li><pclass="first">Definition of the wrapped <spanclass="cb">struct</span>, <ttclass="docutils literal"><spanclass="pre">PyLibrary</span></tt>. It is standard Python here.</p>
<divclass="admonition note">
<pclass="first admonition-title">Note</p>
<pclass="last">For our set of macros to work, the name of the pointer to the
C++ class must always be <strong>_object</strong>, and the various functions and
macros defined here must take the name of the class (either in
lowercase, camel case or capitals).</p>
</div>
</li>
<li><pclass="first">Declaration of the Python type <ttclass="docutils literal"><spanclass="pre">PyTypeLibrary</span></tt> (standard).</p>
</li>
<li><pclass="first">Declaration of the Python type table of methods <ttclass="docutils literal"><spanclass="pre">PyLibrary_Methods</span></tt> (standard).</p>
</li>
</ol>
<olclass="arabic simple"id="id3"start="6">
<li>Declaration of <ttclass="docutils literal"><spanclass="pre">PyLibrary_Link()</span></tt>, helper to convert a C++ <ttclass="docutils literal"><spanclass="pre">Lybrary</span></tt> into
a <ttclass="docutils literal"><spanclass="pre">PyLibrary</span></tt> (put in the support shared library).</li>
<li>Declaration of <ttclass="docutils literal"><spanclass="pre">PyLibrary_LinkPyType()</span></tt>, this function setup the class-level
function of the new Python type (here, <ttclass="docutils literal"><spanclass="pre">PyTypeLibrary</span></tt>).</li>
<li>And, lastly, three macros to:<ul>
<li><ttclass="docutils literal"><spanclass="pre">IsPylibrary()</span></tt>, know if a Python object is a <ttclass="docutils literal"><spanclass="pre">PyLibrary</span></tt></li>
<li><ttclass="docutils literal"><spanclass="pre">PYLIBRARY()</span></tt>, force cast (C style) of a <ttclass="docutils literal"><spanclass="pre">PyObject</span></tt> into a <ttclass="docutils literal"><spanclass="pre">PyLibrary</span></tt>.</li>
<li><ttclass="docutils literal"><spanclass="pre">PYLIBRARY_O()</span></tt>, extract the C++ object (<ttclass="docutils literal"><spanclass="pre">Library*</span></tt>) from the Python
<p>As for the header, all the code must be put inside a <ttclass="docutils literal"><spanclass="pre">extern</span><spanclass="pre">"C"</span></tt> namespace.</p>
<p>A convenience macro <ttclass="docutils literal"><spanclass="pre">METHOD_HEAD()</span></tt> must be defined, by refining
<ttclass="docutils literal"><spanclass="pre">GENERIC_METHOD_HEAD()</span></tt>. This macro will be used in the method wrappers
below to cast the <ttclass="docutils literal"><spanclass="pre">_object</span></tt> field of the Python object into the
appropriate C++ class, this is done using a C-style cast.
The parameters of that macro are:</p>
<olclass="arabic simple">
<li>The C++ encapsulated class (<ttclass="docutils literal"><spanclass="pre">Library</span></tt>).</li>
<li>The name of the <em>variable</em> that will be used to store a pointer
to the C++ working object.</li>
<li>The name of the C++ method which is to be wrapped.</li>
</ol>
</div>
<divclass="section"id="the-python-module-part">
<h3>3.2.2 The Python Module Part<aclass="headerlink"href="#the-python-module-part"title="Permalink to this headline">¶</a></h3>
<p>First, we have to build all the wrappers to the C++ methods of
the class. For common predicates, accessors, and mutators macros
are supplied.</p>
<p>Wrapping of the <ttclass="docutils literal"><spanclass="pre">Library::getCell()</span></tt> method:</p>
<li>The <ttclass="docutils literal"><spanclass="pre">HTRY</span></tt> / <ttclass="docutils literal"><spanclass="pre">HCATCH</span></tt> macros provides an insulation from the C++
exceptions. If one is emitted, it will be catched and transformed in
a Python one. This way, the Python program will be cleanly interrupted
and the usual stack trace displayed.</li>
<li>The returned value of this method is of type <ttclass="docutils literal"><spanclass="pre">Cell*</span></tt>, we have to
transform it into a Python one. This is done with <ttclass="docutils literal"><spanclass="pre">PyCell_Link()</span></tt>.
This macro is supplied by the <ttclass="docutils literal"><spanclass="pre">PyCell.h</span></tt> header and this is why
it must be included.</li>
</ol>
<p></p>
<p>Wrapping of the <ttclass="docutils literal"><spanclass="pre">Library::create()</span></tt> method:</p>
<li>We want the Python interface to mimic as closely as possible the
C++ API. As such, Python object will be created using a static
<ttclass="docutils literal"><spanclass="pre">.create()</span></tt> method. So we do not use the usual Python allocation
mechanism.</li>
<li>As it is a <em>static</em> method, there is no first argument.</li>
<li>Python do not allow function overload like C++. To emulate that
behavior we use the <ttclass="docutils literal"><spanclass="pre">__cs</span></tt> object (which is a global variable).<olclass="arabic">
<li>Init/reset the <ttclass="docutils literal"><spanclass="pre">__cs</span></tt> object: see <em>step (1)</em>.</li>
<li>Call <ttclass="docutils literal"><spanclass="pre">PyArg_ParseTuple()</span></tt>, read every mandatory or optional
argument as a Python object (<ttclass="docutils literal"><spanclass="pre">"O&"</span></tt>) and use <ttclass="docutils literal"><spanclass="pre">Converter</span></tt>
on each one. <ttclass="docutils literal"><spanclass="pre">Converter</span></tt> will determine the real type of
the Python object given as argument by looking at the
encapsulated C++ class. It then update the <ttclass="docutils literal"><spanclass="pre">__cs</span></tt> object.
Done in <em>step (2)</em></li>
<li>After the call to <ttclass="docutils literal"><spanclass="pre">PyArg_ParseTuple()</span></tt>, the function
<ttclass="docutils literal"><spanclass="pre">__cs.getObjectIds()</span></tt> will return the <em>signature</em> of
the various arguments. In our case, the valid signatures
will be <ttclass="docutils literal"><spanclass="pre">":db:string"</span></tt> (<em>step (3.a)*a) and ``”:library:string”``
(*step (3.b)</em>).</li>
<li>Call the C++ method after extracting the C++ objects from
the Python arguments. Note the use of the <ttclass="docutils literal"><spanclass="pre">PYLIBRARY_O()</span></tt>
and <ttclass="docutils literal"><spanclass="pre">PYDATABSE_O()</span></tt> macros to perform the conversion.</li>
</ol>
</li>
<li>Return the result, encapsulated through a call to <ttclass="docutils literal"><spanclass="pre">PyLibrary_Link()</span></tt>.</li>
</ol>
<p></p>
<p>Wrapping of the <ttclass="docutils literal"><spanclass="pre">Library::destroy()</span></tt> method:</p>
<pid="pylibrary-linkpytype">To define <ttclass="docutils literal"><spanclass="pre">PyLibrary_LinkPyType()</span></tt>, use the <ttclass="docutils literal"><spanclass="pre">PyTypeObjectLinkPyType()</span></tt>
macro. This macro is specific for <ttclass="docutils literal"><spanclass="pre">DBo</span></tt> derived classes that are seen as
base classes under Python (i.e. we don’t bother exposing the base
class under Python). <ttclass="docutils literal"><spanclass="pre">PyLibrary_LinkPyType()</span></tt> setup the class functions
in the <ttclass="docutils literal"><spanclass="pre">PyTypeLibrary</span></tt> type object, it <strong>must</strong> be called in the
Python module this class is part of (in this case: <ttclass="docutils literal"><spanclass="pre">PyHurricane.cpp</span></tt>).
This particular flavor of the macro <em>will define</em> and setup the
following class functions:</p>
<ulclass="simple">
<li><ttclass="docutils literal"><spanclass="pre">PyTypeLibrary.tp_compare</span></tt> (defined by the macro).</li>
<li><ttclass="docutils literal"><spanclass="pre">PyTypeLibrary.tp_repr</span></tt> (defined by the macro).</li>
<li><ttclass="docutils literal"><spanclass="pre">PyTypeLibrary.tp_str</span></tt> (defined by the macro).</li>
<li><ttclass="docutils literal"><spanclass="pre">PyTypeLibrary.tp_hash</span></tt> (defined by the macro).</li>
<li><ttclass="docutils literal"><spanclass="pre">PyTypeLibrary.tp_methods</span></tt> sets to the previously defined <ttclass="docutils literal"><spanclass="pre">PyLibrary_Methods</span></tt> table.</li>
<li><ttclass="docutils literal"><spanclass="pre">PyTypeLibrary.tp_dealloc</span></tt> is set to a function that <em>must</em> be named <ttclass="docutils literal"><spanclass="pre">PyLibrary_DeAlloc</span></tt>,
this is what <ttclass="docutils literal"><spanclass="pre">DBoDeleteMethod</span></tt> does. It is <em>not</em> done by <ttclass="docutils literal"><spanclass="pre">PyTypeObjectLinkPyType</span></tt>.</li>
</ul>
<p>Defining the <ttclass="docutils literal"><spanclass="pre">PyTypeLibrary</span></tt> type:</p>
</div>
<divclass="section"id="the-shared-library-part">
<h3>3.2.4 The Shared Library Part<aclass="headerlink"href="#the-shared-library-part"title="Permalink to this headline">¶</a></h3>
<p>This part will be put in a separate supporting shared library, allowing
other Python module to link against it (and make use of its symbols).</p>
<p>To define <ttclass="docutils literal"><spanclass="pre">PyTypeLibrary</span></tt>, use the <ttclass="docutils literal"><spanclass="pre">PyTypeObjectDefinitions()</span></tt> macro.
This macro is specific for classes that, as exposed by Python,
are neither <em>derived</em> classes nor <em>base</em> classes for others.
That is, they are standalone from the inheritance point of view.</p>
<p>The <ttclass="docutils literal"><spanclass="pre">DBoLinkCreateMethod()</span></tt> macro will define the <ttclass="docutils literal"><spanclass="pre">PyLibrary_Link()</span></tt>
function which is responsible for encapsulating a C++ <ttclass="docutils literal"><spanclass="pre">Library</span></tt> object
into a Python <ttclass="docutils literal"><spanclass="pre">PyLibrary</span></tt> one.</p>
<h2>3.3 Python Module (C++ namespace)<aclass="headerlink"href="#python-module-c-namespace"title="Permalink to this headline">¶</a></h2>
<p>We use the Python module to replicate the C++ <em>namespace</em>. Thus, for the
<ttclass="docutils literal"><spanclass="pre">Hurricane</span></tt> namespace we create a Python <ttclass="docutils literal"><spanclass="pre">Hurricane</span></tt> module which is
defined in the <ttclass="docutils literal"><spanclass="pre">PyHurricane.cpp</span></tt> file, then we add into that module
dictionary all the Python types encapsulating the C++ classes of that
<p>The <ttclass="docutils literal"><spanclass="pre">initHurricane()</span></tt> initialisation function shown above has
been scrubbed of everything not relevant to the <ttclass="docutils literal"><spanclass="pre">PyLibrary</span></tt> class.
The integration of the <ttclass="docutils literal"><spanclass="pre">PyLibrary</span></tt> class into the module needs
four steps:</p>
<olclass="arabic">
<li><pclass="first">A call to <aclass="reference internal"href="#pylibrary-linkpytype">PyLibrary_LinkPyType()</a> to hook the Python type functions
in the Python type object.</p>
</li>
<li><pclass="first">A call to the <ttclass="docutils literal"><spanclass="pre">PYTYPE_READY()</span></tt> macro (standard Python).</p>
</li>
<li><pclass="first">Registering the type into the <ttclass="docutils literal"><spanclass="pre">__cs</span></tt> object, with <ttclass="docutils literal"><spanclass="pre">addType()</span></tt>.
The arguments are self explanatory, save for the last which is a
boolean to tell if this is a <em>derived</em> class or not.</p>
</li>
<li><pclass="first">Adding the type object (<ttclass="docutils literal"><spanclass="pre">PyTypeLibrary</span></tt>) into the dictionnary of
the module itself. This allow to mimic closely the C++ syntax:</p>