mirror of
https://github.com/boostorg/python.git
synced 2026-01-24 06:02:14 +00:00
Doc Tweaks
[SVN r32910]
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%">
|
||||
<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../people/people.htm">People</a></td>
|
||||
@@ -31,7 +31,7 @@
|
||||
<div><p class="copyright">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="id427816"></a><p>
|
||||
<a name="id372676"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
@@ -83,18 +83,18 @@
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.quickstart"></a>QuickStart</h2></div></div></div>
|
||||
<p>
|
||||
QuickStartThe Boost Python Library is a framework for interfacing Python and
|
||||
C++. It allows you to quickly and seamlessly expose C++ classes functions and
|
||||
objects to Python, and vice-versa, using no special tools -- just your C++
|
||||
compiler. It is designed to wrap C++ interfaces non-intrusively, so that you
|
||||
should not have to change the C++ code at all in order to wrap it, making Boost.Python
|
||||
The Boost Python Library is a framework for interfacing Python and C++. It
|
||||
allows you to quickly and seamlessly expose C++ classes functions and objects
|
||||
to Python, and vice-versa, using no special tools -- just your C++ compiler.
|
||||
It is designed to wrap C++ interfaces non-intrusively, so that you should not
|
||||
have to change the C++ code at all in order to wrap it, making Boost.Python
|
||||
ideal for exposing 3rd-party libraries to Python. The library's use of advanced
|
||||
metaprogramming techniques simplifies its syntax for users, so that wrapping
|
||||
code takes on the look of a kind of declarative interface definition language
|
||||
(IDL).
|
||||
</p>
|
||||
<a name="quickstart.hello_world"></a><h2>
|
||||
<a name="id372244"></a>
|
||||
<a name="id372867"></a>
|
||||
Hello World
|
||||
</h2>
|
||||
<p>
|
||||
@@ -123,19 +123,23 @@
|
||||
That's it. We're done. We can now build this as a shared library. The resulting
|
||||
DLL is now visible to Python. Here's a sample Python session:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
<span class="identifier">hello</span><span class="special">,</span> <span class="identifier">world</span>
|
||||
</pre>
|
||||
<p></p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p><span class="emphasis"><em><span class="bold"><b>Next stop... Building your Hello World module
|
||||
from start to finish...</b></span></em></span></p></blockquote></div>
|
||||
<p>
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<span class="emphasis"><em><span class="bold"><b>Next stop... Building your Hello World module
|
||||
from start to finish...</b></span></em></span>
|
||||
</p></blockquote></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><small><p>Last revised: October 31, 2005 at 18:46:06 GMT</p></small></td>
|
||||
<td align="left"><small><p>Last revised: February 14, 2006 at 02:23:06 GMT</p></small></td>
|
||||
<td align="right"><small></small></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%">
|
||||
<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
@@ -27,19 +27,20 @@
|
||||
<a name="python.embedding"></a>Embedding</h2></div></div></div>
|
||||
<div class="toc"><dl><dt><span class="section"><a href="embedding.html#python.using_the_interpreter">Using the interpreter</a></span></dt></dl></div>
|
||||
<p>
|
||||
EmbeddingBy now you should know how to use Boost.Python to call your C++ code
|
||||
from Python. However, sometimes you may need to do the reverse: call Python
|
||||
code from the C++-side. This requires you to <span class="emphasis"><em>embed</em></span> the
|
||||
Python interpreter into your C++ program.
|
||||
By now you should know how to use Boost.Python to call your C++ code from Python.
|
||||
However, sometimes you may need to do the reverse: call Python code from the
|
||||
C++-side. This requires you to <span class="emphasis"><em>embed</em></span> the Python interpreter
|
||||
into your C++ program.
|
||||
</p>
|
||||
<p>
|
||||
Currently, Boost.Python does not directly support everything you'll need when
|
||||
embedding. Therefore you'll need to use the <a href="http://www.python.org/doc/current/api/api.html" target="_top">Python/C
|
||||
API</a> to fill in the gaps. However, Boost.Python already makes embedding
|
||||
a lot easier and, in a future version, it may become unnecessary to touch the
|
||||
Python/C API at all. So stay tuned... <span class="inlinemediaobject"><img src="../images/smiley.png"></span></p>
|
||||
Python/C API at all. So stay tuned... <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
|
||||
</p>
|
||||
<a name="embedding.building_embedded_programs"></a><h2>
|
||||
<a name="id457321"></a>
|
||||
<a name="id458605"></a>
|
||||
Building embedded programs
|
||||
</h2>
|
||||
<p>
|
||||
@@ -83,7 +84,7 @@ exe embedded_program # name of the executable
|
||||
<find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
|
||||
</pre>
|
||||
<a name="embedding.getting_started"></a><h2>
|
||||
<a name="id457409"></a>
|
||||
<a name="id458703"></a>
|
||||
Getting started
|
||||
</h2>
|
||||
<p>
|
||||
@@ -92,7 +93,9 @@ exe embedded_program # name of the executable
|
||||
</p>
|
||||
<div class="orderedlist"><ol type="1">
|
||||
<li>
|
||||
#include <tt class="literal"><boost/python.hpp></tt><br><br>
|
||||
|
||||
#include
|
||||
<tt class="literal"><boost/python.hpp></tt><br><br>
|
||||
</li>
|
||||
<li>
|
||||
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652" target="_top">Py_Initialize</a>()
|
||||
@@ -110,24 +113,25 @@ exe embedded_program # name of the executable
|
||||
<p>
|
||||
(Of course, there can be other C++ code between all of these steps.)
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p><span class="emphasis"><em><span class="bold"><b>Now that we can embed the interpreter in
|
||||
our programs, lets see how to put it to use...</b></span></em></span></p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<span class="emphasis"><em><span class="bold"><b>Now that we can embed the interpreter in
|
||||
our programs, lets see how to put it to use...</b></span></em></span>
|
||||
</p></blockquote></div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
|
||||
<p>
|
||||
Using the interpreterAs you probably already know, objects in Python are
|
||||
reference-counted. Naturally, the <tt class="literal">PyObject</tt>s of the Python/C
|
||||
API are also reference-counted. There is a difference however. While the
|
||||
reference-counting is fully automatic in Python, the Python/C API requires
|
||||
you to do it <a href="http://www.python.org/doc/current/api/refcounts.html" target="_top">by
|
||||
As you probably already know, objects in Python are reference-counted. Naturally,
|
||||
the <tt class="literal">PyObject</tt>s of the Python/C API are also reference-counted.
|
||||
There is a difference however. While the reference-counting is fully automatic
|
||||
in Python, the Python/C API requires you to do it <a href="http://www.python.org/doc/current/api/refcounts.html" target="_top">by
|
||||
hand</a>. This is messy and especially hard to get right in the presence
|
||||
of C++ exceptions. Fortunately Boost.Python provides the <a href="../../../../v2/handle.html" target="_top">handle</a>
|
||||
and <a href="../../../../v2/object.html" target="_top">object</a> class templates to
|
||||
automate the process.
|
||||
</p>
|
||||
<a name="using_the_interpreter.reference_counting_handles_and_objects"></a><h2>
|
||||
<a name="id457544"></a>
|
||||
<a name="id458870"></a>
|
||||
Reference-counting handles and objects
|
||||
</h2>
|
||||
<p>
|
||||
@@ -163,17 +167,18 @@ exe embedded_program # name of the executable
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png"></span> <span class="bold"><b>Handle is a class <span class="emphasis"><em>template</em></span>, so why
|
||||
haven't we been using any template parameters?</b></span><br><br><tt class="literal">handle</tt> has a single template parameter specifying
|
||||
the type of the managed object. This type is <tt class="literal">PyObject</tt>
|
||||
99% of the time, so the parameter was defaulted to <tt class="literal">PyObject</tt>
|
||||
for convenience. Therefore we can use the shorthand <tt class="literal">handle<></tt>
|
||||
instead of the longer, but equivalent, <tt class="literal">handle<PyObject></tt>.
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Handle is a class
|
||||
<span class="emphasis"><em>template</em></span>, so why haven't we been using any template
|
||||
parameters?</b></span><br> <br> <tt class="literal">handle</tt> has a
|
||||
single template parameter specifying the type of the managed object.
|
||||
This type is <tt class="literal">PyObject</tt> 99% of the time, so the parameter
|
||||
was defaulted to <tt class="literal">PyObject</tt> for convenience. Therefore
|
||||
we can use the shorthand <tt class="literal">handle<></tt> instead
|
||||
of the longer, but equivalent, <tt class="literal">handle<PyObject></tt>.
|
||||
</td></tr></tbody>
|
||||
</table></div>
|
||||
<a name="using_the_interpreter.running_python_code"></a><h2>
|
||||
<a name="id457863"></a>
|
||||
<a name="id459217"></a>
|
||||
Running Python code
|
||||
</h2>
|
||||
<p>
|
||||
@@ -184,7 +189,8 @@ exe embedded_program # name of the executable
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">PyObject</span><span class="special">*</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="keyword">char</span> <span class="special">*</span><span class="identifier">str</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">PyObject</span> <span class="special">*</span><span class="identifier">globals</span><span class="special">,</span> <span class="identifier">PyObject</span> <span class="special">*</span><span class="identifier">locals</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
|
||||
<p>
|
||||
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
|
||||
takes the code to execute as a null-terminated (C-style) string in its <tt class="literal">str</tt>
|
||||
parameter. The function returns a new reference to a Python object. Which
|
||||
object is returned depends on the <tt class="literal">start</tt> paramater.
|
||||
@@ -195,8 +201,9 @@ exe embedded_program # name of the executable
|
||||
</p>
|
||||
<div class="informaltable">
|
||||
<h4>
|
||||
<a name="id458033"></a><span class="table-title">Start symbols</span>
|
||||
</h4>
|
||||
<a name="id459396"></a>
|
||||
<span class="table-title">Start symbols</span>
|
||||
</h4>
|
||||
<table class="table">
|
||||
<colgroup>
|
||||
<col>
|
||||
@@ -269,8 +276,8 @@ exe embedded_program # name of the executable
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png"></span> <span class="bold"><b>Note</b></span> that we wrap the return value of <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Note</b></span> that
|
||||
we wrap the return value of <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
|
||||
in a (nameless) <tt class="literal">handle</tt> even though we are not interested
|
||||
in it. If we didn't do this, the the returned object would be kept
|
||||
alive unnecessarily. Unless you want to be a Dr. Frankenstein, always
|
||||
@@ -278,7 +285,7 @@ exe embedded_program # name of the executable
|
||||
</td></tr></tbody>
|
||||
</table></div>
|
||||
<a name="using_the_interpreter.beyond_handles"></a><h2>
|
||||
<a name="id458506"></a>
|
||||
<a name="id459921"></a>
|
||||
Beyond handles
|
||||
</h2>
|
||||
<p>
|
||||
@@ -326,15 +333,15 @@ exe embedded_program # name of the executable
|
||||
</pre>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png"></span> <span class="bold"><b>Note</b></span> that <tt class="literal">object</tt>'s member
|
||||
function to return the wrapped <tt class="literal">PyObject*</tt> is called
|
||||
<tt class="literal">ptr</tt> instead of <tt class="literal">get</tt>. This makes
|
||||
sense if you take into account the different functions that <tt class="literal">object</tt>
|
||||
and <tt class="literal">handle</tt> perform. </td></tr></tbody>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Note</b></span> that
|
||||
<tt class="literal">object</tt>'s member function to return the wrapped
|
||||
<tt class="literal">PyObject*</tt> is called <tt class="literal">ptr</tt> instead
|
||||
of <tt class="literal">get</tt>. This makes sense if you take into account
|
||||
the different functions that <tt class="literal">object</tt> and <tt class="literal">handle</tt>
|
||||
perform. </td></tr></tbody>
|
||||
</table></div>
|
||||
<a name="using_the_interpreter.exception_handling"></a><h2>
|
||||
<a name="id459120"></a>
|
||||
<a name="id460562"></a>
|
||||
Exception handling
|
||||
</h2>
|
||||
<p>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%">
|
||||
<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
@@ -26,10 +26,9 @@
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.exception"></a> Exception Translation</h2></div></div></div>
|
||||
<p>
|
||||
Exception TranslationAll C++ exceptions must be caught at the boundary with
|
||||
Python code. This boundary is the point where C++ meets Python. Boost.Python
|
||||
provides a default exception handler that translates selected standard exceptions,
|
||||
then gives up:
|
||||
All C++ exceptions must be caught at the boundary with Python code. This boundary
|
||||
is the point where C++ meets Python. Boost.Python provides a default exception
|
||||
handler that translates selected standard exceptions, then gives up:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">raise</span> <span class="identifier">RuntimeError</span><span class="special">,</span> <span class="string">'unidentifiable C++ Exception'</span>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%">
|
||||
<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dt><span class="section"><a href="exposing.html#python.class_operators_special_functions">Class Operators/Special Functions</a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
Exposing ClassesNow let's expose a C++ class to Python.
|
||||
Now let's expose a C++ class to Python.
|
||||
</p>
|
||||
<p>
|
||||
Consider a C++ class/struct that we want to expose to Python:
|
||||
@@ -69,7 +69,8 @@
|
||||
we may use our class <tt class="literal">World</tt> in Python. Here's a sample Python
|
||||
session:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
|
||||
@@ -81,10 +82,10 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.constructors"></a>Constructors</h3></div></div></div>
|
||||
<p>
|
||||
ConstructorsOur previous example didn't have any explicit constructors. Since
|
||||
<tt class="literal">World</tt> is declared as a plain struct, it has an implicit
|
||||
default constructor. Boost.Python exposes the default constructor by default,
|
||||
which is why we were able to write
|
||||
Our previous example didn't have any explicit constructors. Since <tt class="literal">World</tt>
|
||||
is declared as a plain struct, it has an implicit default constructor. Boost.Python
|
||||
exposes the default constructor by default, which is why we were able to
|
||||
write
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
|
||||
@@ -93,7 +94,8 @@
|
||||
We may wish to wrap a class with a non-default constructor. Let us build
|
||||
on our previous example:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">World</span>
|
||||
<span class="special">{</span>
|
||||
@@ -121,7 +123,8 @@
|
||||
<span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p><tt class="literal">init<std::string>()</tt> exposes the constructor taking
|
||||
<p>
|
||||
<tt class="literal">init<std::string>()</tt> exposes the constructor taking
|
||||
in a <tt class="literal">std::string</tt> (in Python, constructors are spelled
|
||||
"<tt class="literal">"<span class="underline">_init</span>_"</tt>").
|
||||
</p>
|
||||
@@ -153,9 +156,9 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_data_members"></a>Class Data Members</h3></div></div></div>
|
||||
<p>
|
||||
Class Data MembersData members may also be exposed to Python so that they
|
||||
can be accessed as attributes of the corresponding Python class. Each data
|
||||
member that we wish to be exposed may be regarded as <span class="bold"><b>read-only</b></span>
|
||||
Data members may also be exposed to Python so that they can be accessed as
|
||||
attributes of the corresponding Python class. Each data member that we wish
|
||||
to be exposed may be regarded as <span class="bold"><b>read-only</b></span>
|
||||
or <span class="bold"><b>read-write</b></span>. Consider this class <tt class="literal">Var</tt>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
@@ -179,7 +182,8 @@
|
||||
Then, in Python, assuming we have placed our Var class inside the namespace
|
||||
hello as we did before:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">Var</span><span class="special">(</span><span class="string">'pi'</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
|
||||
@@ -201,13 +205,13 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_properties"></a>Class Properties</h3></div></div></div>
|
||||
<p>
|
||||
Class PropertiesIn C++, classes with public data members are usually frowned
|
||||
upon. Well designed classes that take advantage of encapsulation hide the
|
||||
class' data members. The only way to access the class' data is through access
|
||||
(getter/setter) functions. Access functions expose class properties. Here's
|
||||
an example:
|
||||
In C++, classes with public data members are usually frowned upon. Well designed
|
||||
classes that take advantage of encapsulation hide the class' data members.
|
||||
The only way to access the class' data is through access (getter/setter)
|
||||
functions. Access functions expose class properties. Here's an example:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<p></p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Num</span>
|
||||
<span class="special">{</span>
|
||||
@@ -231,7 +235,8 @@
|
||||
<p>
|
||||
And at last, in Python:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Num</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
|
||||
@@ -244,7 +249,8 @@
|
||||
<span class="bold"><b>read-only</b></span> since the <tt class="literal">rovalue</tt>
|
||||
setter member function is not passed in:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
|
||||
</pre>
|
||||
@@ -253,7 +259,7 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.inheritance"></a>Inheritance</h3></div></div></div>
|
||||
<p>
|
||||
InheritanceIn the previous examples, we dealt with classes that are not polymorphic.
|
||||
In the previous examples, we dealt with classes that are not polymorphic.
|
||||
This is not often the case. Much of the time, we will be wrapping polymorphic
|
||||
classes and class hierarchies related by inheritance. We will often have
|
||||
to write Boost.Python wrappers for classes that are derived from abstract
|
||||
@@ -335,9 +341,9 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_virtual_functions"></a>Class Virtual Functions</h3></div></div></div>
|
||||
<p>
|
||||
Class Virtual FunctionsIn this section, we shall learn how to make functions
|
||||
behave polymorphically through virtual functions. Continuing our example,
|
||||
let us add a virtual function to our <tt class="literal">Base</tt> class:
|
||||
In this section, we shall learn how to make functions behave polymorphically
|
||||
through virtual functions. Continuing our example, let us add a virtual function
|
||||
to our <tt class="literal">Base</tt> class:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Base</span>
|
||||
@@ -375,10 +381,10 @@
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span><br><br> If you are using
|
||||
Microsoft Visual C++ 6 or 7, you have to write <tt class="computeroutput"><span class="identifier">f</span></tt>
|
||||
as:<br><br><tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="keyword">this</span><span class="special">-></span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">).</span><span class="identifier">ptr</span><span class="special">());</span></tt>.</td></tr></tbody>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span><br>
|
||||
<br> If you are using Microsoft Visual C++ 6 or 7, you have to write
|
||||
<tt class="computeroutput"><span class="identifier">f</span></tt> as:<br> <br>
|
||||
<tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="keyword">this</span><span class="special">-></span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">).</span><span class="identifier">ptr</span><span class="special">());</span></tt>.</td></tr></tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
BaseWrap's overridden virtual member function <tt class="computeroutput"><span class="identifier">f</span></tt>
|
||||
@@ -392,16 +398,17 @@
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">pure_virtual</span><span class="special">(&</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">))</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p><tt class="computeroutput"><span class="identifier">pure_virtual</span></tt> signals Boost.Python
|
||||
<p>
|
||||
<tt class="computeroutput"><span class="identifier">pure_virtual</span></tt> signals Boost.Python
|
||||
that the function <tt class="computeroutput"><span class="identifier">f</span></tt> is a
|
||||
pure virtual function.
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png"></span> <span class="bold"><b>member function and methods</b></span><br><br> Python,
|
||||
like many object oriented languages uses the term <span class="bold"><b>methods</b></span>.
|
||||
Methods correspond roughly to C++'s <span class="bold"><b>member functions</b></span>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>member function and
|
||||
methods</b></span><br> <br> Python, like many object oriented languages
|
||||
uses the term <span class="bold"><b>methods</b></span>. Methods correspond
|
||||
roughly to C++'s <span class="bold"><b>member functions</b></span>
|
||||
</td></tr></tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
@@ -409,11 +416,10 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.virtual_functions_with_default_implementations"></a>Virtual Functions with Default Implementations</h3></div></div></div>
|
||||
<p>
|
||||
Virtual Functions with Default ImplementationsWe've seen in the previous
|
||||
section how classes with pure virtual functions are wrapped using Boost.Python's
|
||||
<a href="../../../../v2/wrapper.html" target="_top">class wrapper</a> facilities. If
|
||||
we wish to wrap <span class="bold"><b>non</b></span>-pure-virtual functions
|
||||
instead, the mechanism is a bit different.
|
||||
We've seen in the previous section how classes with pure virtual functions
|
||||
are wrapped using Boost.Python's <a href="../../../../v2/wrapper.html" target="_top">class
|
||||
wrapper</a> facilities. If we wish to wrap <span class="bold"><b>non</b></span>-pure-virtual
|
||||
functions instead, the mechanism is a bit different.
|
||||
</p>
|
||||
<p>
|
||||
Recall that in the <a href="exposing.html#python.class_virtual_functions" title="Class Virtual Functions">previous
|
||||
@@ -460,10 +466,9 @@
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span><br><br> If you are using
|
||||
Microsoft Visual C++ 6 or 7, you have to rewrite the line with the
|
||||
<tt class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></tt> as:<br><br><tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*>(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></tt>.</td></tr></tbody>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span><br>
|
||||
<br> If you are using Microsoft Visual C++ 6 or 7, you have to rewrite
|
||||
the line with the <tt class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></tt> as:<br> <br> <tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*>(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></tt>.</td></tr></tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
Finally, exposing:
|
||||
@@ -482,7 +487,8 @@
|
||||
<p>
|
||||
In Python, the results would be as expected:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">base</span> <span class="special">=</span> <span class="identifier">Base</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="keyword">class</span> <span class="identifier">Derived</span><span class="special">(</span><span class="identifier">Base</span><span class="special">):</span>
|
||||
@@ -509,9 +515,9 @@
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_operators_special_functions"></a>Class Operators/Special Functions</h3></div></div></div>
|
||||
<a name="class_operators_special_functions.class_operators_special_functionspython_operators"></a><h2>
|
||||
<a name="id447955"></a>
|
||||
Class Operators/Special FunctionsPython Operators
|
||||
<a name="class_operators_special_functions.python_operators"></a><h2>
|
||||
<a name="id448928"></a>
|
||||
Python Operators
|
||||
</h2>
|
||||
<p>
|
||||
C is well known for the abundance of operators. C++ extends this to the extremes
|
||||
@@ -522,7 +528,8 @@
|
||||
Consider a file position class <tt class="literal">FilePos</tt> and a set of operators
|
||||
that take on FilePos instances:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span>
|
||||
|
||||
@@ -558,7 +565,7 @@
|
||||
expressions".
|
||||
</p>
|
||||
<a name="class_operators_special_functions.special_methods"></a><h2>
|
||||
<a name="id448698"></a>
|
||||
<a name="id449680"></a>
|
||||
Special Methods
|
||||
</h2>
|
||||
<p>
|
||||
@@ -588,9 +595,7 @@
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png"></span>
|
||||
What is the business of <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></tt>? Well, the method <tt class="computeroutput"><span class="identifier">str</span></tt> requires the <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></tt> to do its work (i.e. <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></tt>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> What is the business of <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></tt>? Well, the method <tt class="computeroutput"><span class="identifier">str</span></tt> requires the <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></tt> to do its work (i.e. <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></tt>
|
||||
is used by the method defined by <tt class="computeroutput"><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span></tt>.</td></tr></tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%">
|
||||
<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
@@ -32,13 +32,15 @@
|
||||
<dt><span class="section"><a href="functions.html#python.auto_overloading">Auto-Overloading</a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
FunctionsIn this chapter, we'll look at Boost.Python powered functions in closer
|
||||
detail. We shall see some facilities to make exposing C++ functions to Python
|
||||
safe from potential pifalls such as dangling pointers and references. We shall
|
||||
also see facilities that will make it even easier for us to expose C++ functions
|
||||
In this chapter, we'll look at Boost.Python powered functions in closer detail.
|
||||
We shall see some facilities to make exposing C++ functions to Python safe
|
||||
from potential pifalls such as dangling pointers and references. We shall also
|
||||
see facilities that will make it even easier for us to expose C++ functions
|
||||
that take advantage of C++ features such as overloading and default arguments.
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p><span class="emphasis"><em>Read on...</em></span></p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<span class="emphasis"><em>Read on...</em></span>
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
But before you do, you might want to fire up Python 2.2 or later and type
|
||||
<tt class="literal">>>> import this</tt>.
|
||||
@@ -69,15 +71,15 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.call_policies"></a>Call Policies</h3></div></div></div>
|
||||
<p>
|
||||
Call PoliciesIn C++, we often deal with arguments and return types such as
|
||||
pointers and references. Such primitive types are rather, ummmm, low level
|
||||
and they really don't tell us much. At the very least, we don't know the
|
||||
owner of the pointer or the referenced object. No wonder languages such as
|
||||
Java and Python never deal with such low level entities. In C++, it's usually
|
||||
considered a good practice to use smart pointers which exactly describe ownership
|
||||
semantics. Still, even good C++ interfaces use raw references and pointers
|
||||
sometimes, so Boost.Python must deal with them. To do this, it may need your
|
||||
help. Consider the following C++ function:
|
||||
In C++, we often deal with arguments and return types such as pointers and
|
||||
references. Such primitive types are rather, ummmm, low level and they really
|
||||
don't tell us much. At the very least, we don't know the owner of the pointer
|
||||
or the referenced object. No wonder languages such as Java and Python never
|
||||
deal with such low level entities. In C++, it's usually considered a good
|
||||
practice to use smart pointers which exactly describe ownership semantics.
|
||||
Still, even good C++ interfaces use raw references and pointers sometimes,
|
||||
so Boost.Python must deal with them. To do this, it may need your help. Consider
|
||||
the following C++ function:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">X</span><span class="special">&</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
@@ -135,7 +137,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
We could copy result into a new object:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">).</span><span class="identifier">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="comment"># Result disappears
|
||||
</span><span class="special">>>></span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="comment"># No crash, but still bad
|
||||
@@ -149,7 +152,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<p>
|
||||
Our problems do not end there. Suppose Y is implemented as follows:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">struct</span> <span class="identifier">Y</span>
|
||||
<span class="special">{</span>
|
||||
@@ -202,7 +206,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<li><span class="bold"><b>BOOM!</b></span></li>
|
||||
</ol></div>
|
||||
<a name="call_policies.call_policies"></a><h2>
|
||||
<a name="id450599"></a>
|
||||
<a name="id451559"></a>
|
||||
Call Policies
|
||||
</h2>
|
||||
<p>
|
||||
@@ -285,20 +289,19 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</ul></div>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/smiley.png"></span> <span class="bold"><b>Remember the Zen, Luke:</b></span><br><br> "Explicit
|
||||
is better than implicit"<br> "In the face of ambiguity,
|
||||
refuse the temptation to guess"<br>
|
||||
</td></tr></tbody>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><b>Remember the Zen, Luke:</b></span><br>
|
||||
<br> "Explicit is better than implicit"<br> "In
|
||||
the face of ambiguity, refuse the temptation to guess"<br>
|
||||
</td></tr></tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.overloading"></a>Overloading</h3></div></div></div>
|
||||
<p>
|
||||
OverloadingThe following illustrates a scheme for manually wrapping an overloaded
|
||||
member functions. Of course, the same technique can be applied to wrapping
|
||||
overloaded non-member functions.
|
||||
The following illustrates a scheme for manually wrapping an overloaded member
|
||||
functions. Of course, the same technique can be applied to wrapping overloaded
|
||||
non-member functions.
|
||||
</p>
|
||||
<p>
|
||||
We have here our C++ class:
|
||||
@@ -351,8 +354,8 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.default_arguments"></a>Default Arguments</h3></div></div></div>
|
||||
<p>
|
||||
Default ArgumentsBoost.Python wraps (member) function pointers. Unfortunately,
|
||||
C++ function pointers carry no default argument info. Take a function <tt class="literal">f</tt>
|
||||
Boost.Python wraps (member) function pointers. Unfortunately, C++ function
|
||||
pointers carry no default argument info. Take a function <tt class="literal">f</tt>
|
||||
with default arguments:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
@@ -401,7 +404,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
</li>
|
||||
</ul></div>
|
||||
<a name="default_arguments.boost_python_function_overloads"></a><h2>
|
||||
<a name="id452559"></a>
|
||||
<a name="id453611"></a>
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
<p>
|
||||
@@ -431,7 +434,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
</pre>
|
||||
<a name="default_arguments.boost_python_member_function_overloads"></a><h2>
|
||||
<a name="id452863"></a>
|
||||
<a name="id453927"></a>
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
<p>
|
||||
@@ -477,7 +480,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
reference</a> for details.
|
||||
</p>
|
||||
<a name="default_arguments.init_and_optional"></a><h2>
|
||||
<a name="id453212"></a>
|
||||
<a name="id454288"></a>
|
||||
init and optional
|
||||
</h2>
|
||||
<p>
|
||||
@@ -507,10 +510,10 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.auto_overloading"></a>Auto-Overloading</h3></div></div></div>
|
||||
<p>
|
||||
Auto-OverloadingIt was mentioned in passing in the previous section that
|
||||
<tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt> and <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
|
||||
can also be used for overloaded functions and member functions with a common
|
||||
sequence of initial arguments. Here is an example:
|
||||
It was mentioned in passing in the previous section that <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>
|
||||
and <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> can also be
|
||||
used for overloaded functions and member functions with a common sequence
|
||||
of initial arguments. Here is an example:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
|
||||
@@ -551,7 +554,7 @@ Namespaces are one honking great idea -- let's do more of those!
|
||||
(0) arguments and a maximum of 3 arguments.
|
||||
</p>
|
||||
<a name="auto_overloading.manual_wrapping"></a><h2>
|
||||
<a name="id453917"></a>
|
||||
<a name="id455013"></a>
|
||||
Manual Wrapping
|
||||
</h2>
|
||||
<p>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%">
|
||||
<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
@@ -25,9 +25,9 @@
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.hello"></a> Building Hello World</h2></div></div></div>
|
||||
<a name="hello._building_hello_worldfrom_start_to_finish"></a><h2>
|
||||
<a name="id442456"></a>
|
||||
Building Hello WorldFrom Start To Finish
|
||||
<a name="hello.from_start_to_finish"></a><h2>
|
||||
<a name="id373240"></a>
|
||||
From Start To Finish
|
||||
</h2>
|
||||
<p>
|
||||
Now the first thing you'd want to do is to build the Hello World module and
|
||||
@@ -37,11 +37,11 @@
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png"></span> <span class="bold"><b>Building without bjam</b></span><br><br> Besides bjam,
|
||||
there are of course other ways to get your module built. What's written
|
||||
here should not be taken as "the one and only way". There are
|
||||
of course other build tools apart from <tt class="literal">bjam</tt>.<br><br> Take note however that the preferred build tool for Boost.Python
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Building without bjam</b></span><br>
|
||||
<br> Besides bjam, there are of course other ways to get your module
|
||||
built. What's written here should not be taken as "the one and only
|
||||
way". There are of course other build tools apart from <tt class="literal">bjam</tt>.<br>
|
||||
<br> Take note however that the preferred build tool for Boost.Python
|
||||
is bjam. There are so many ways to set up the build incorrectly. Experience
|
||||
shows that 90% of the "I can't build Boost.Python" problems
|
||||
come from people who had to use a different tool. </td></tr></tbody>
|
||||
@@ -99,10 +99,12 @@
|
||||
platforms. The complete list of Bjam executables can be found <a href="http://sourceforge.net/project/showfiles.php?group_id=7586" target="_top">here</a>.
|
||||
</p>
|
||||
<a name="hello.let_s_jam_"></a><h2>
|
||||
<a name="id373799"></a>
|
||||
<a name="id373448"></a>
|
||||
Let's Jam!
|
||||
</h2>
|
||||
<p><span class="inlinemediaobject"><img src="../images/jam.png"></span></p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/jam.png" alt="jam"></span>
|
||||
</p>
|
||||
<p>
|
||||
Here is our minimalist Jamfile:
|
||||
</p>
|
||||
@@ -148,10 +150,11 @@ extension hello # Declare a Python extension called hello
|
||||
The last part tells BJam that we are depending on the Boost Python Library.
|
||||
</p>
|
||||
<a name="hello.running_bjam"></a><h2>
|
||||
<a name="id373910"></a>
|
||||
<a name="id373586"></a>
|
||||
Running bjam
|
||||
</h2>
|
||||
<p><span class="emphasis"><em>bjam</em></span> is run using your operating system's command line
|
||||
<p>
|
||||
<span class="emphasis"><em>bjam</em></span> is run using your operating system's command line
|
||||
interpreter.
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
@@ -177,10 +180,8 @@ set PYTHON_VERSION=2.2
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/tip.png"></span>
|
||||
Be sure not to include a third number, e.g. <span class="bold"><b>not</b></span>
|
||||
"2.2.1", even if that's the version you have.</td></tr></tbody>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> Be sure not to include a third number, e.g. <span class="bold"><b>not</b></span> "2.2.1", even if that's the version
|
||||
you have.</td></tr></tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
Take note that you may also do that through the Jamrules file we put in our
|
||||
@@ -251,23 +252,29 @@ b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp
|
||||
<p>
|
||||
if you are on Unix.
|
||||
</p>
|
||||
<p><tt class="literal">boost_python.dll</tt> and <tt class="literal">hello.pyd</tt> can be
|
||||
<p>
|
||||
<tt class="literal">boost_python.dll</tt> and <tt class="literal">hello.pyd</tt> can be
|
||||
found somewhere in your project's <tt class="literal">bin</tt> directory. After a
|
||||
successful build, you can just link in these DLLs with the Python interpreter.
|
||||
In Windows for example, you can simply put these libraries inside the directory
|
||||
where the Python executable is.
|
||||
successful build, you make it possible for the system to find boost_python.dll
|
||||
or libboost_python.so (usually done with LD_LIBRARY_PATH, DYLD_LIBRARY_PATH,
|
||||
or some other variable on *nix and with PATH on Windows) and for Python to
|
||||
find the hello module (Done with PYTHONPATH on all systems.)
|
||||
</p>
|
||||
<p>
|
||||
You may now fire up Python and run our hello module:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
<span class="identifier">hello</span><span class="special">,</span> <span class="identifier">world</span>
|
||||
</pre>
|
||||
<p></p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p><span class="bold"><b>There you go... Have fun!</b></span></p></blockquote></div>
|
||||
<p>
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<span class="bold"><b>There you go... Have fun!</b></span>
|
||||
</p></blockquote></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%">
|
||||
<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
@@ -26,10 +26,12 @@
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.iterators"></a>Iterators</h2></div></div></div>
|
||||
<p>
|
||||
IteratorsIn C++, and STL in particular, we see iterators everywhere. Python
|
||||
also has iterators, but these are two very different beasts.
|
||||
In C++, and STL in particular, we see iterators everywhere. Python also has
|
||||
iterators, but these are two very different beasts.
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><b>C++ iterators:</b></span>
|
||||
</p>
|
||||
<p><span class="bold"><b>C++ iterators:</b></span></p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
C++ has 5 type categories (random-access, bidirectional, forward, input,
|
||||
@@ -42,7 +44,9 @@
|
||||
A pair of iterators is needed to represent a (first/last) range.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p><span class="bold"><b>Python Iterators:</b></span></p>
|
||||
<p>
|
||||
<span class="bold"><b>Python Iterators:</b></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
1 category (forward)
|
||||
@@ -58,7 +62,8 @@
|
||||
The typical Python iteration protocol: <tt class="literal"><span class="bold"><b>for y
|
||||
in x...</b></span></tt> is as follows:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
|
||||
</span><span class="keyword">try</span><span class="special">:</span>
|
||||
@@ -72,7 +77,8 @@
|
||||
as Python iterators. What we need to do is to produce appropriate <tt class="computeroutput"><span class="identifier">__iter__</span></tt> function from C++ iterators that
|
||||
is compatible with the Python iteration protocol. For example:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>();</span>
|
||||
<span class="identifier">object</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">get_iterator</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
|
||||
@@ -84,7 +90,9 @@
|
||||
<pre class="programlisting">
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>())</span>
|
||||
</pre>
|
||||
<p><span class="bold"><b>range</b></span></p>
|
||||
<p>
|
||||
<span class="bold"><b>range</b></span>
|
||||
</p>
|
||||
<p>
|
||||
We can create a Python savvy iterator using the range function:
|
||||
</p>
|
||||
@@ -110,7 +118,9 @@
|
||||
adaptable function object (use Target parameter)
|
||||
</li>
|
||||
</ul></div>
|
||||
<p><span class="bold"><b>iterator</b></span></p>
|
||||
<p>
|
||||
<span class="bold"><b>iterator</b></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc"><li>
|
||||
iterator<T, Policies>()
|
||||
</li></ul></div>
|
||||
@@ -122,7 +132,8 @@
|
||||
Let's put this into action... Here's an example from some hypothetical bogon
|
||||
Particle accelerator code:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
|
||||
<span class="keyword">for</span> <span class="identifier">x</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">pions</span><span class="special">:</span>
|
||||
@@ -133,13 +144,16 @@
|
||||
<p>
|
||||
Now, our C++ Wrapper:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">F</span><span class="special">>(</span><span class="string">"Field"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"pions"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_begin</span><span class="special">,</span> <span class="special">&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_end</span><span class="special">))</span>
|
||||
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"bogons"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_begin</span><span class="special">,</span> <span class="special">&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_end</span><span class="special">));</span>
|
||||
</pre>
|
||||
<p><span class="bold"><b>stl_input_iterator</b></span></p>
|
||||
<p>
|
||||
<span class="bold"><b>stl_input_iterator</b></span>
|
||||
</p>
|
||||
<p>
|
||||
So far, we have seen how to expose C++ iterators and ranges to Python. Sometimes
|
||||
we wish to go the other way, though: we'd like to pass a Python sequence to
|
||||
@@ -147,7 +161,8 @@
|
||||
a Python iterator look like an STL iterator. For that, we use <tt class="computeroutput"><span class="identifier">stl_input_iterator</span><span class="special"><></span></tt>.
|
||||
Consider how we might implement a function that exposes <tt class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">assign</span><span class="special">()</span></tt> to Python:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">void</span> <span class="identifier">list_assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">o</span><span class="special">)</span> <span class="special">{</span>
|
||||
@@ -166,7 +181,8 @@
|
||||
Now in Python, we can assign any integer sequence to <tt class="computeroutput"><span class="identifier">list_int</span></tt>
|
||||
objects:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
|
||||
<span class="identifier">x</span><span class="special">.</span><span class="identifier">assign</span><span class="special">([</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">,</span><span class="number">5</span><span class="special">])</span>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%">
|
||||
<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
@@ -32,11 +32,11 @@
|
||||
<dt><span class="section"><a href="object.html#python.enums">Enums</a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
Object InterfacePython is dynamically typed, unlike C++ which is statically
|
||||
typed. Python variables may hold an integer, a float, list, dict, tuple, str,
|
||||
long etc., among other things. In the viewpoint of Boost.Python and C++, these
|
||||
Pythonic variables are just instances of class <tt class="literal">object</tt>. We
|
||||
shall see in this chapter how to deal with Python objects.
|
||||
Python is dynamically typed, unlike C++ which is statically typed. Python variables
|
||||
may hold an integer, a float, list, dict, tuple, str, long etc., among other
|
||||
things. In the viewpoint of Boost.Python and C++, these Pythonic variables
|
||||
are just instances of class <tt class="literal">object</tt>. We shall see in this
|
||||
chapter how to deal with Python objects.
|
||||
</p>
|
||||
<p>
|
||||
As mentioned, one of the goals of Boost.Python is to provide a bidirectional
|
||||
@@ -44,21 +44,24 @@
|
||||
C++ <tt class="literal">object</tt>s are as close as possible to Python. This should
|
||||
minimize the learning curve significantly.
|
||||
</p>
|
||||
<p><span class="inlinemediaobject"><img src="../images/python.png"></span></p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/python.png" alt="python"></span>
|
||||
</p>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.basic_interface"></a>Basic Interface</h3></div></div></div>
|
||||
<p>
|
||||
Basic InterfaceClass <tt class="literal">object</tt> wraps <tt class="literal">PyObject*</tt>.
|
||||
All the intricacies of dealing with <tt class="literal">PyObject</tt>s such as
|
||||
managing reference counting are handled by the <tt class="literal">object</tt>
|
||||
class. C++ object interoperability is seamless. Boost.Python C++ <tt class="literal">object</tt>s
|
||||
Class <tt class="literal">object</tt> wraps <tt class="literal">PyObject*</tt>. All the
|
||||
intricacies of dealing with <tt class="literal">PyObject</tt>s such as managing
|
||||
reference counting are handled by the <tt class="literal">object</tt> class. C++
|
||||
object interoperability is seamless. Boost.Python C++ <tt class="literal">object</tt>s
|
||||
can in fact be explicitly constructed from any C++ object.
|
||||
</p>
|
||||
<p>
|
||||
To illustrate, this Python code snippet:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">):</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">'foo'</span><span class="special">):</span>
|
||||
@@ -73,7 +76,8 @@
|
||||
<p>
|
||||
Can be rewritten in C++ using Boost.Python facilities this way:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">object</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">"foo"</span><span class="special">)</span>
|
||||
@@ -95,8 +99,8 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.derived_object_types"></a>Derived Object types</h3></div></div></div>
|
||||
<p>
|
||||
Derived Object typesBoost.Python comes with a set of derived <tt class="literal">object</tt>
|
||||
types corresponding to that of Python's:
|
||||
Boost.Python comes with a set of derived <tt class="literal">object</tt> types
|
||||
corresponding to that of Python's:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
@@ -133,7 +137,8 @@
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
|
||||
</pre>
|
||||
<p><tt class="literal">make_tuple</tt> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
|
||||
<p>
|
||||
<tt class="literal">make_tuple</tt> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
@@ -173,10 +178,9 @@
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png"></span> <span class="bold"><b>Beware</b></span> the common pitfall of forgetting that
|
||||
the constructors of most of Python's mutable types make copies, just
|
||||
as in Python. </td></tr></tbody>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>Beware</b></span> the
|
||||
common pitfall of forgetting that the constructors of most of Python's
|
||||
mutable types make copies, just as in Python. </td></tr></tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
Python:
|
||||
@@ -193,7 +197,7 @@
|
||||
</span><span class="identifier">d</span><span class="special">[</span><span class="char">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies the copy
|
||||
</span></pre>
|
||||
<a name="derived_object_types.class__lt_t_gt__as_objects"></a><h2>
|
||||
<a name="id455806"></a>
|
||||
<a name="id457004"></a>
|
||||
class_<T> as objects
|
||||
</h2>
|
||||
<p>
|
||||
@@ -218,9 +222,9 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.extracting_c___objects"></a>Extracting C++ objects</h3></div></div></div>
|
||||
<p>
|
||||
Extracting C++ objectsAt some point, we will need to get C++ values out of
|
||||
object instances. This can be achieved with the <tt class="literal">extract<T></tt>
|
||||
function. Consider the following:
|
||||
At some point, we will need to get C++ values out of object instances. This
|
||||
can be achieved with the <tt class="literal">extract<T></tt> function. Consider
|
||||
the following:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">);</span> <span class="comment">// compile error
|
||||
@@ -253,8 +257,8 @@
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">check</span><span class="special">())</span> <span class="special">{</span>
|
||||
<span class="identifier">Vec2</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">();</span> <span class="special">...</span>
|
||||
</pre>
|
||||
<p><span class="inlinemediaobject"><img src="../images/tip.png"></span>
|
||||
The astute reader might have noticed that the <tt class="literal">extract<T></tt>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> The astute reader might have noticed that the <tt class="literal">extract<T></tt>
|
||||
facility in fact solves the mutable copying problem:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
@@ -266,12 +270,12 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.enums"></a>Enums</h3></div></div></div>
|
||||
<p>
|
||||
EnumsBoost.Python has a nifty facility to capture and wrap C++ enums. While
|
||||
Python has no <tt class="literal">enum</tt> type, we'll often want to expose our
|
||||
C++ enums to Python as an <tt class="literal">int</tt>. Boost.Python's enum facility
|
||||
makes this easy while taking care of the proper conversions from Python's
|
||||
dynamic typing to C++'s strong static typing (in C++, ints cannot be implicitly
|
||||
converted to enums). To illustrate, given a C++ enum:
|
||||
Boost.Python has a nifty facility to capture and wrap C++ enums. While Python
|
||||
has no <tt class="literal">enum</tt> type, we'll often want to expose our C++ enums
|
||||
to Python as an <tt class="literal">int</tt>. Boost.Python's enum facility makes
|
||||
this easy while taking care of the proper conversions from Python's dynamic
|
||||
typing to C++'s strong static typing (in C++, ints cannot be implicitly converted
|
||||
to enums). To illustrate, given a C++ enum:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">enum</span> <span class="identifier">choice</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
|
||||
@@ -293,16 +297,17 @@
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png"></span> <span class="bold"><b>what is a scope?</b></span><br><br> The scope is a
|
||||
class that has an associated global Python object which controls the
|
||||
Python namespace in which new extension classes and wrapped functions
|
||||
will be defined as attributes. Details can be found <a href="../../../../v2/scope.html" target="_top">here</a>.</td></tr></tbody>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>what is a scope?</b></span><br>
|
||||
<br> The scope is a class that has an associated global Python object
|
||||
which controls the Python namespace in which new extension classes
|
||||
and wrapped functions will be defined as attributes. Details can be
|
||||
found <a href="../../../../v2/scope.html" target="_top">here</a>.</td></tr></tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
You can access those values in Python as
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
<span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
@@ -311,7 +316,8 @@
|
||||
where my_module is the module where the enum is declared. You can also create
|
||||
a new scope around a class:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">scope</span> <span class="identifier">in_X</span> <span class="special">=</span> <span class="identifier">class_</span><span class="special"><</span><span class="identifier">X</span><span class="special">>(</span><span class="string">"X"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%">
|
||||
<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
@@ -30,16 +30,16 @@
|
||||
<dt><span class="section"><a href="techniques.html#python.reducing_compiling_time">Reducing Compiling Time</a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
General TechniquesHere are presented some useful techniques that you can use
|
||||
while wrapping code with Boost.Python.
|
||||
Here are presented some useful techniques that you can use while wrapping code
|
||||
with Boost.Python.
|
||||
</p>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.creating_packages"></a>Creating Packages</h3></div></div></div>
|
||||
<p>
|
||||
Creating PackagesA Python package is a collection of modules that provide
|
||||
to the user a certain functionality. If you're not familiar on how to create
|
||||
packages, a good introduction to them is provided in the <a href="http://www.python.org/doc/current/tut/node8.html" target="_top">Python
|
||||
A Python package is a collection of modules that provide to the user a certain
|
||||
functionality. If you're not familiar on how to create packages, a good introduction
|
||||
to them is provided in the <a href="http://www.python.org/doc/current/tut/node8.html" target="_top">Python
|
||||
Tutorial</a>.
|
||||
</p>
|
||||
<p>
|
||||
@@ -98,12 +98,10 @@
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png"></span>
|
||||
The extension <tt class="literal">.pyd</tt> is used for python extension
|
||||
modules, which are just shared libraries. Using the default for your
|
||||
system, like <tt class="literal">.so</tt> for Unix and <tt class="literal">.dll</tt>
|
||||
for Windows, works just as well.</td></tr></tbody>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> The extension <tt class="literal">.pyd</tt> is used
|
||||
for python extension modules, which are just shared libraries. Using
|
||||
the default for your system, like <tt class="literal">.so</tt> for Unix and
|
||||
<tt class="literal">.dll</tt> for Windows, works just as well.</td></tr></tbody>
|
||||
</table></div>
|
||||
<p>
|
||||
Now, we create this directory structure for our Python package:
|
||||
@@ -124,7 +122,8 @@
|
||||
into his <a href="http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000" target="_top">PYTHONPATH</a>
|
||||
and fire up the interpreter:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span>
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
@@ -146,7 +145,8 @@
|
||||
If we want this flexibility, we will have to complicate our package hierarchy
|
||||
a little. First, we will have to change the name of the extension modules:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="comment">/* file core.cpp */</span>
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_core</span><span class="special">)</span>
|
||||
@@ -178,7 +178,8 @@
|
||||
to each one. But if we leave it that way, the user will have to access the
|
||||
functions in the core module with this syntax:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span>
|
||||
<span class="special">>>></span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span><span class="special">.</span><span class="identifier">foo</span><span class="special">(...)</span>
|
||||
@@ -237,8 +238,8 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.extending_wrapped_objects_in_python"></a>Extending Wrapped Objects in Python</h3></div></div></div>
|
||||
<p>
|
||||
Extending Wrapped Objects in PythonThanks to Python's flexibility, you can
|
||||
easily add new methods to a class, even after it was already created:
|
||||
Thanks to Python's flexibility, you can easily add new methods to a class,
|
||||
even after it was already created:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="special">>>></span> <span class="keyword">class</span> <span class="identifier">C</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span> <span class="keyword">pass</span>
|
||||
@@ -256,12 +257,14 @@
|
||||
<span class="identifier">A</span> <span class="identifier">C</span> <span class="identifier">instance</span><span class="special">!</span>
|
||||
</pre>
|
||||
<p>
|
||||
Yes, Python rox. <span class="inlinemediaobject"><img src="../images/smiley.png"></span></p>
|
||||
Yes, Python rox. <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
|
||||
</p>
|
||||
<p>
|
||||
We can do the same with classes that were wrapped with Boost.Python. Suppose
|
||||
we have a class <tt class="literal">point</tt> in C++:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">class</span> <span class="identifier">point</span> <span class="special">{...};</span>
|
||||
|
||||
@@ -274,7 +277,8 @@
|
||||
If we are using the technique from the previous session, <a href="techniques.html#python.creating_packages" title="Creating Packages">Creating
|
||||
Packages</a>, we can code directly into <tt class="literal">geom/__init__.py</tt>:
|
||||
</p>
|
||||
<p></p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
|
||||
@@ -285,7 +289,8 @@
|
||||
<span class="comment"># now we turn it into a member function
|
||||
</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">point_str</span>
|
||||
</pre>
|
||||
<p><span class="bold"><b>All</b></span> point instances created from C++ will
|
||||
<p>
|
||||
<span class="bold"><b>All</b></span> point instances created from C++ will
|
||||
also have this member function! This technique has several advantages:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
@@ -357,12 +362,13 @@
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.reducing_compiling_time"></a>Reducing Compiling Time</h3></div></div></div>
|
||||
<p>
|
||||
Reducing Compiling TimeIf you have ever exported a lot of classes, you know
|
||||
that it takes quite a good time to compile the Boost.Python wrappers. Plus
|
||||
the memory consumption can easily become too high. If this is causing you
|
||||
problems, you can split the class_ definitions in multiple files:
|
||||
If you have ever exported a lot of classes, you know that it takes quite
|
||||
a good time to compile the Boost.Python wrappers. Plus the memory consumption
|
||||
can easily become too high. If this is causing you problems, you can split
|
||||
the class_ definitions in multiple files:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<p></p>
|
||||
<pre class="programlisting">
|
||||
<span class="comment">/* file point.cpp */</span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
@@ -421,19 +427,16 @@
|
||||
</p>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png"></span>
|
||||
If you're exporting your classes with <a href="../../../../../pyste/index.html" target="_top">Pyste</a>,
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> If you're exporting your classes with <a href="../../../../../pyste/index.html" target="_top">Pyste</a>,
|
||||
take a look at the <tt class="literal">--multiple</tt> option, that generates
|
||||
the wrappers in various files as demonstrated here.</td></tr></tbody>
|
||||
</table></div>
|
||||
<div class="informaltable"><table class="table">
|
||||
<colgroup><col></colgroup>
|
||||
<tbody><tr><td class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png"></span>
|
||||
This method is useful too if you are getting the error message <span class="emphasis"><em>"fatal
|
||||
error C1204:Compiler limit:internal structure overflow"</em></span>
|
||||
when compiling a large source file, as explained in the <a href="../../../../v2/faq.html#c1204" target="_top">FAQ</a>.</td></tr></tbody>
|
||||
<tbody><tr><td class="blurb"> <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> This method is useful too if you are getting the
|
||||
error message <span class="emphasis"><em>"fatal error C1204:Compiler limit:internal
|
||||
structure overflow"</em></span> when compiling a large source file,
|
||||
as explained in the <a href="../../../../v2/faq.html#c1204" target="_top">FAQ</a>.</td></tr></tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -252,9 +252,10 @@ if you are on Windows, and
|
||||
if you are on Unix.
|
||||
|
||||
[^boost_python.dll] and [^hello.pyd] can be found somewhere in your project's
|
||||
[^bin] directory. After a successful build, you can just link in these DLLs with
|
||||
the Python interpreter. In Windows for example, you can simply put these libraries
|
||||
inside the directory where the Python executable is.
|
||||
[^bin] directory. After a successful build, you make it possible for the system
|
||||
to find boost_python.dll or libboost_python.so (usually done with LD_LIBRARY_PATH,
|
||||
DYLD_LIBRARY_PATH, or some other variable on *nix and with PATH on Windows) and
|
||||
for Python to find the hello module (Done with PYTHONPATH on all systems.)
|
||||
|
||||
You may now fire up Python and run our hello module:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user