📄 sipref.html
字号:
<p>Using the SIP build system is simply a matter of writing a small Python script.In this simple example we will assume that the <tt class="docutils literal"><span class="pre">word</span></tt> library we are wrappingand it's header file are installed in standard system locations and will befound by the compiler and linker without having to specify any additionalflags. In a more realistic example your Python script may take command lineoptions, or search a set of directories to deal with different configurationsand installations.</p><p>This is the simplest script (conventionally called <tt class="docutils literal"><span class="pre">configure.py</span></tt>):</p><pre class="literal-block">import osimport sipconfig# The name of the SIP build file generated by SIP and used by the build# system.build_file = "word.sbf"# Get the SIP configuration information.config = sipconfig.Configuration()# Run SIP to generate the code.os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "word.sip"]))# Create the Makefile.makefile = sipconfig.SIPModuleMakefile(config, build_file)# Add the library we are wrapping. The name doesn't include any platform# specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the# ".dll" extension on Windows).makefile.extra_libs = ["word"]# Generate the Makefile itself.makefile.generate()</pre><p>Hopefully this script is self-documenting. The key parts are the<tt class="docutils literal"><span class="pre">Configuration</span></tt> and <tt class="docutils literal"><span class="pre">SIPModuleMakefile</span></tt> classes. The build system containsother Makefile classes, for example to build programs or to call otherMakefiles in sub-directories.</p><p>After running the script (using the Python interpreter the extension module isbeing created for) the generated C++ code and <tt class="docutils literal"><span class="pre">Makefile</span></tt> will be in thecurrent directory.</p><p>To compile and install the extension module, just run the followingcommands <a class="footnote-reference" href="#id6" id="id3" name="id3">[3]</a>:</p><pre class="literal-block">makemake install</pre><p>That's all there is to it.</p><p>See <a class="reference" href="#building-your-extension-with-distutils">Building Your Extension with distutils</a> for an example of how to buildthis example using distutils.</p><table class="docutils footnote" frame="void" id="id4" rules="none"><colgroup><col class="label" /><col /></colgroup><tbody valign="top"><tr><td class="label"><a class="fn-backref" href="#id1" name="id4">[1]</a></td><td>All SIP directives start with a <tt class="docutils literal"><span class="pre">%</span></tt> as the first non-whitespacecharacter of a line.</td></tr></tbody></table><table class="docutils footnote" frame="void" id="id5" rules="none"><colgroup><col class="label" /><col /></colgroup><tbody valign="top"><tr><td class="label"><a class="fn-backref" href="#id2" name="id5">[2]</a></td><td>SIP includes many code directives like this. They differ in where thesupplied code is placed by SIP in the generated code.</td></tr></tbody></table><table class="docutils footnote" frame="void" id="id6" rules="none"><colgroup><col class="label" /><col /></colgroup><tbody valign="top"><tr><td class="label"><a class="fn-backref" href="#id3" name="id6">[3]</a></td><td>On Windows you might run <tt class="docutils literal"><span class="pre">nmake</span></tt> or <tt class="docutils literal"><span class="pre">mingw32-make</span></tt> instead.</td></tr></tbody></table></div><div class="section" id="id7"><h2><a class="toc-backref" href="#id38" name="id7">4.2 A Simple C Example</a></h2><p>Let's now look at a very similar example of wrapping a fictional C library:</p><pre class="literal-block">/* Define the interface to the word library. */struct Word { const char *the_word;};struct Word *create_word(const char *w);char *reverse(struct Word *word);</pre><p>The corresponding SIP specification file would then look something like this:</p><pre class="literal-block">/* Define the SIP wrapper to the word library. */%CModule word 0struct Word {%TypeHeaderCode#include <word.h>%End const char *the_word;};struct Word *create_word(const char *w) /Factory/;char *reverse(struct Word *word);</pre><p>Again, let's look at the differences between the two files.</p><blockquote><ul class="simple"><li>The <a class="reference" href="#cmodule">%CModule</a> directive has been added. This has the same syntax asthe <a class="reference" href="#module">%Module</a> directive used in the previous example but tells SIP thatthe library being wrapped is implemented in C rather than C++.</li><li>The <a class="reference" href="#typeheadercode">%TypeHeaderCode</a> directive has been added.</li><li>The <a class="reference" href="#factory">Factory</a> annotation has been added to the <tt class="docutils literal"><span class="pre">create_word()</span></tt> function.This tells SIP that a newly created structure is being returned and it isowned by Python.</li></ul></blockquote><p>The <tt class="docutils literal"><span class="pre">configure.py</span></tt> build system script described in the previous example canbe used for this example without change.</p></div><div class="section" id="a-more-complex-c-example"><h2><a class="toc-backref" href="#id39" name="a-more-complex-c-example">4.3 A More Complex C++ Example</a></h2><p>In this last example we will wrap a fictional C++ library that contains a classthat is derived from a Qt class. This will demonstrate how SIP allows a classhierarchy to be split across multiple Python extension modules, and willintroduce SIP's versioning system.</p><p>The library contains a single C++ class called <tt class="docutils literal"><span class="pre">Hello</span></tt> which is derived fromQt's <tt class="docutils literal"><span class="pre">QLabel</span></tt> class. It behaves just like <tt class="docutils literal"><span class="pre">QLabel</span></tt> except that the textin the label is hard coded to be <tt class="docutils literal"><span class="pre">Hello</span> <span class="pre">World</span></tt>. To make the example moreinteresting we'll also say that the library only supports Qt v3.0 and later,and also includes a function called <tt class="docutils literal"><span class="pre">setDefault()</span></tt> that is not implementedin the Windows version of the library.</p><p>The <tt class="docutils literal"><span class="pre">hello.h</span></tt> header file looks something like this:</p><pre class="literal-block">// Define the interface to the hello library.#include <qlabel.h>#include <qwidget.h>#include <qstring.h>class Hello : public QLabel { // This is needed by the Qt Meta-Object Compiler. Q_OBJECTpublic: Hello(QWidget *parent, const char *name = 0, WFlags f = 0);private: // Prevent instances from being copied. Hello(const Hello &); Hello &operator=(const Hello &);};#if !defined(Q_OS_WIN)void setDefault(const QString &def);#endif</pre><p>The corresponding SIP specification file would then look something like this:</p><pre class="literal-block">// Define the SIP wrapper to the hello library.%Module hello 0%Import qt/qtmod.sip%If (Qt_3_0_0 -)class Hello : QLabel {%TypeHeaderCode#include <hello.h>%Endpublic: Hello(QWidget *parent /TransferThis/, const char *name = 0, WFlags f = 0);private: Hello(const Hello &);};%If (!WS_WIN)void setDefault(const QString &def);%End%End</pre><p>Again we look at the differences, but we'll skip those that we've looked at inprevious examples.</p><blockquote><ul class="simple"><li>The <a class="reference" href="#import">%Import</a> directive has been added to specify that we are extendingthe class hierarchy defined in the file <tt class="docutils literal"><span class="pre">qt/qtmod.sip</span></tt>. This file ispart of PyQt. The build system will take care of finding the file'sexact location.</li><li>The <a class="reference" href="#if">%If</a> directive has been added to specify thateverything <a class="footnote-reference" href="#id11" id="id8" name="id8">[4]</a> up to the matching <a class="reference" href="#end">%End</a> directive only applies to Qtv3.0 and later. <tt class="docutils literal"><span class="pre">Qt_3_0_0</span></tt> is a <em>tag</em> defined in <tt class="docutils literal"><span class="pre">qtmod.sip</span></tt> <a class="footnote-reference" href="#id12" id="id9" name="id9">[5]</a>using the <a class="reference" href="#timeline">%Timeline</a> directive. <a class="reference" href="#timeline">%Timeline</a> is used to define a tagfor each version of a library's API you are wrapping allowing you tomaintain all the different versions in a single SIP specification. Thebuild system provides support to <tt class="docutils literal"><span class="pre">configure.py</span></tt> scripts for working outthe correct tags to use according to which version of the library isactually installed.</li>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -