2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-19 16:32:16 +00:00

tutorial update

[SVN r40734]
This commit is contained in:
Joel de Guzman
2007-11-04 00:12:29 +00:00
parent 6a3085ad5d
commit 597dfc586b
13 changed files with 686 additions and 806 deletions

View File

@@ -3,21 +3,21 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter 1. python 1.0</title>
<link rel="stylesheet" href="boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="index.html" title="Chapter 1. python 1.0">
<link rel="next" href="python/hello.html" title="Building Hello World">
<link rel="next" href="python/hello.html" title=" Building Hello World">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<table cellpadding="2" width="100%"><tr>
<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>
<td align="center"><a href="../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</table>
</tr></table>
<hr>
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="images/next.png" alt="Next"></a></div>
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a></div>
<div class="chapter" lang="en">
<div class="titlepage"><div>
<div><h2 class="title">
@@ -31,7 +31,7 @@
<div><p class="copyright">Copyright © 2002-2005 Joel
de Guzman, David Abrahams</p></div>
<div><div class="legalnotice">
<a name="id2632684"></a><p>
<a name="id385505"></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>)
@@ -93,10 +93,10 @@
code takes on the look of a kind of declarative interface definition language
(IDL).
</p>
<a name="quickstart.hello_world"></a><h3>
<a name="id2595112"></a>
<a name="quickstart.hello_world"></a><h2>
<a name="id455837"></a>
Hello World
</h3>
</h2>
<p>
Following C/C++ tradition, let's start with the "hello, world". A
C++ Function:
@@ -112,10 +112,10 @@
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello_ext</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
<span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="identifier">greet</span><span class="special">);</span>
<span class="special">}</span>
</pre>
@@ -126,7 +126,7 @@
<p>
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello</span>
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
<span class="special">&gt;&gt;&gt;</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>
@@ -136,8 +136,8 @@
<p>
</p>
<p>
<span class="emphasis"><em><span class="bold"><strong>Next stop... Building your Hello World
module from start to finish...</strong></span></em></span>
<span class="emphasis"><em><span class="bold"><b>Next stop... Building your Hello World
module from start to finish...</b></span></em></span>
</p>
<p>
</p>
@@ -145,10 +145,10 @@
</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: May 18, 2007 at 15:46:01 GMT</p></small></td>
<td align="left"><p><small>Last revised: November 04, 2007 at 00:10:08 GMT</small></p></td>
<td align="right"><small></small></td>
</tr></table>
<hr>
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="images/next.png" alt="Next"></a></div>
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a></div>
</body>
</html>

View File

@@ -3,24 +3,24 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Embedding</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="object.html" title="Object Interface">
<link rel="prev" href="object.html" title=" Object Interface">
<link rel="next" href="iterators.html" title="Iterators">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<table cellpadding="2" width="100%"><tr>
<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>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</table>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="object.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="object.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@@ -39,28 +39,28 @@
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" alt="smiley"></span>
</p>
<a name="embedding.building_embedded_programs"></a><h3>
<a name="id2654982"></a>
<a name="embedding.building_embedded_programs"></a><h2>
<a name="id471088"></a>
Building embedded programs
</h3>
</h2>
<p>
To be able to embed python into your programs, you have to link to both Boost.Python's
as well as Python's own runtime library.
</p>
<p>
Boost.Python's library comes in two variants. Both are located in Boost's
<code class="literal">/libs/python/build/bin-stage</code> subdirectory. On Windows, the
variants are called <code class="literal">boost_python.lib</code> (for release builds)
and <code class="literal">boost_python_debug.lib</code> (for debugging). If you can't
<tt class="literal">/libs/python/build/bin-stage</tt> subdirectory. On Windows, the
variants are called <tt class="literal">boost_python.lib</tt> (for release builds)
and <tt class="literal">boost_python_debug.lib</tt> (for debugging). If you can't
find the libraries, you probably haven't built Boost.Python yet. See <a href="../../../../building.html" target="_top">Building and Testing</a> on how to do this.
</p>
<p>
Python's library can be found in the <code class="literal">/libs</code> subdirectory
Python's library can be found in the <tt class="literal">/libs</tt> subdirectory
of your Python directory. On Windows it is called pythonXY.lib where X.Y is
your major Python version number.
</p>
<p>
Additionally, Python's <code class="literal">/include</code> subdirectory has to be added
Additionally, Python's <tt class="literal">/include</tt> subdirectory has to be added
to your include path.
</p>
<p>
@@ -81,35 +81,37 @@ exe embedded_program # name of the executable
&lt;library-path&gt;$(PYTHON_LIB_PATH)
&lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
</pre>
<a name="embedding.getting_started"></a><h3>
<a name="id2655076"></a>
<a name="embedding.getting_started"></a><h2>
<a name="id471193"></a>
Getting started
</h3>
</h2>
<p>
Being able to build is nice, but there is nothing to build yet. Embedding the
Python interpreter into one of your C++ programs requires these 4 steps:
</p>
<div class="orderedlist"><ol type="1">
<li>
#include <code class="literal">&lt;boost/python.hpp&gt;</code><br><br>
#include <tt class="literal">&lt;boost/python.hpp&gt;</tt>
</li>
<li>
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652" target="_top">Py_Initialize</a>()
to start the interpreter and create the <code class="literal"><span class="underline">_main</span>_</code>
module.<br><br>
</li>
to start the interpreter and create the <tt class="literal"><span class="underline">_main</span>_</tt>
module.
</li>
<li>
Call other Python C API routines to use the interpreter.<br><br>
</li>
Call other Python C API routines to use the interpreter.
</li>
</ol></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>Note that at this time you must
not call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
to stop the interpreter. This may be fixed in a future version of boost.python.</strong></span>
</p>
</div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td colspan="2" align="left" valign="top"><p>
<span class="bold"><b>Note that at this time you must not call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
to stop the interpreter. This may be fixed in a future version of boost.python.</b></span>
</p></td></tr>
</table></div>
<p>
(Of course, there can be other C++ code between all of these steps.)
</p>
@@ -117,8 +119,8 @@ exe embedded_program # name of the executable
<p>
</p>
<p>
<span class="emphasis"><em><span class="bold"><strong>Now that we can embed the interpreter in
our programs, lets see how to put it to use...</strong></span></em></span>
<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>
<p>
</p>
@@ -128,7 +130,7 @@ exe embedded_program # name of the executable
<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
<p>
As you probably already know, objects in Python are reference-counted. Naturally,
the <code class="literal">PyObject</code>s of the Python/C API are also reference-counted.
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<span class="emphasis"><em>C API requires you to do it [@http:</em></span>/www.python.org/doc/current/api/refcounts.html
by hand]. This is messy and especially hard to get right in the presence
@@ -136,10 +138,10 @@ exe embedded_program # name of the executable
and <a href="../../../../v2/object.html" target="_top">object</a> class templates to
automate the process.
</p>
<a name="using_the_interpreter.running_python_code"></a><h3>
<a name="id2655255"></a>
<a name="using_the_interpreter.running_python_code"></a><h2>
<a name="id471356"></a>
Running Python code
</h3>
</h2>
<p>
Boost.python provides three related functions to run Python code from C++.
</p>
@@ -154,10 +156,10 @@ exe embedded_program # name of the executable
and exec_file executes the code contained in the given file.
</p>
<p>
The <code class="literal">globals</code> and <code class="literal">locals</code> parameters are
The <tt class="literal">globals</tt> and <tt class="literal">locals</tt> parameters are
Python dictionaries containing the globals and locals of the context in which
to run the code. For most intents and purposes you can use the namespace
dictionary of the <code class="literal"><span class="underline">_main</span>_</code>
dictionary of the <tt class="literal"><span class="underline">_main</span>_</tt>
module for both parameters.
</p>
<p>
@@ -171,7 +173,7 @@ exe embedded_program # name of the executable
first), and returns it.
</p>
<p>
Let's import the <code class="literal"><span class="underline">_main</span>_</code>
Let's import the <tt class="literal"><span class="underline">_main</span>_</tt>
module and run some Python code in its namespace:
</p>
<pre class="programlisting">
@@ -187,15 +189,15 @@ exe embedded_program # name of the executable
This should create a file called 'hello.txt' in the current directory containing
a phrase that is well-known in programming circles.
</p>
<a name="using_the_interpreter.manipulating_python_objects"></a><h3>
<a name="id2655783"></a>
<a name="using_the_interpreter.manipulating_python_objects"></a><h2>
<a name="id471944"></a>
Manipulating Python objects
</h3>
</h2>
<p>
Often we'd like to have a class to manipulate Python objects. But we have
already seen such a class above, and in the <a href="object.html" target="_top">previous
section</a>: the aptly named <code class="literal">object</code> class and its
derivatives. We've already seen that they can be constructed from a <code class="literal">handle</code>.
section</a>: the aptly named <tt class="literal">object</tt> class and its
derivatives. We've already seen that they can be constructed from a <tt class="literal">handle</tt>.
The following examples should further illustrate this fact:
</p>
<pre class="programlisting">
@@ -205,7 +207,7 @@ exe embedded_program # name of the executable
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">main_namespace</span><span class="special">[</span><span class="string">"result"</span><span class="special">]);</span>
</pre>
<p>
Here we create a dictionary object for the <code class="literal"><span class="underline">_main</span>_</code>
Here we create a dictionary object for the <tt class="literal"><span class="underline">_main</span>_</tt>
module's namespace. Then we assign 5 squared to the result variable and read
this variable from the dictionary. Another way to achieve the same result
is to use eval instead, which returns the result directly:
@@ -214,10 +216,10 @@ exe embedded_program # name of the executable
<span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
</pre>
<a name="using_the_interpreter.exception_handling"></a><h3>
<a name="id2656116"></a>
<a name="using_the_interpreter.exception_handling"></a><h2>
<a name="id472316"></a>
Exception handling
</h3>
</h2>
<p>
If an exception occurs in the evaluation of the python expression, <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>
is thrown:
@@ -235,7 +237,7 @@ exe embedded_program # name of the executable
</span><span class="special">}</span>
</pre>
<p>
The <code class="literal">error_already_set</code> exception class doesn't carry any
The <tt class="literal">error_already_set</tt> exception class doesn't carry any
information in itself. To find out more about the Python exception that occurred,
you need to use the <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">exception
handling functions</a> of the Python<span class="emphasis"><em>C API in your catch-statement.
@@ -271,7 +273,7 @@ exe embedded_program # name of the executable
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="object.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="object.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -1,26 +1,26 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Exception Translation</title>
<title> Exception Translation</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="iterators.html" title="Iterators">
<link rel="next" href="techniques.html" title="General Techniques">
<link rel="next" href="techniques.html" title=" General Techniques">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<table cellpadding="2" width="100%"><tr>
<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>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</table>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="iterators.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="iterators.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@@ -54,7 +54,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="iterators.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="iterators.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -1,26 +1,26 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Exposing Classes</title>
<title> Exposing Classes</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="hello.html" title="Building Hello World">
<link rel="prev" href="hello.html" title=" Building Hello World">
<link rel="next" href="functions.html" title="Functions">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<table cellpadding="2" width="100%"><tr>
<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>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</table>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="hello.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="hello.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@@ -64,9 +64,9 @@
<span class="special">}</span>
</pre>
<p>
Here, we wrote a C++ class wrapper that exposes the member functions <code class="literal">greet</code>
and <code class="literal">set</code>. Now, after building our module as a shared library,
we may use our class <code class="literal">World</code> in Python. Here's a sample Python
Here, we wrote a C++ class wrapper that exposes the member functions <tt class="literal">greet</tt>
and <tt class="literal">set</tt>. Now, after building our module as a shared library,
we may use our class <tt class="literal">World</tt> in Python. Here's a sample Python
session:
</p>
<p>
@@ -82,7 +82,7 @@
<div class="titlepage"><div><div><h3 class="title">
<a name="python.constructors"></a>Constructors</h3></div></div></div>
<p>
Our previous example didn't have any explicit constructors. Since <code class="literal">World</code>
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
@@ -106,9 +106,9 @@
<span class="special">};</span>
</pre>
<p>
This time <code class="literal">World</code> has no default constructor; our previous
This time <tt class="literal">World</tt> has no default constructor; our previous
wrapping code would fail to compile when the library tried to expose it.
We have to tell <code class="literal">class_&lt;World&gt;</code> about the constructor
We have to tell <tt class="literal">class_&lt;World&gt;</tt> about the constructor
we want to expose instead.
</p>
<pre class="programlisting">
@@ -124,13 +124,13 @@
<span class="special">}</span>
</pre>
<p>
<code class="literal">init&lt;std::string&gt;()</code> exposes the constructor taking
in a <code class="literal">std::string</code> (in Python, constructors are spelled
"<code class="literal">"<span class="underline">_init</span>_"</code>").
<tt class="literal">init&lt;std::string&gt;()</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>
<p>
We can expose additional constructors by passing more <code class="literal">init&lt;...&gt;</code>s
to the <code class="literal">def()</code> member function. Say for example we have
We can expose additional constructors by passing more <tt class="literal">init&lt;...&gt;</tt>s
to the <tt class="literal">def()</tt> member function. Say for example we have
another World constructor taking in two doubles:
</p>
<pre class="programlisting">
@@ -142,13 +142,13 @@
</pre>
<p>
On the other hand, if we do not wish to expose any constructors at all, we
may use <code class="literal">no_init</code> instead:
may use <tt class="literal">no_init</tt> instead:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Abstract</span><span class="special">&gt;(</span><span class="string">"Abstract"</span><span class="special">,</span> <span class="identifier">no_init</span><span class="special">)</span>
</pre>
<p>
This actually adds an <code class="literal"><span class="underline">_init</span>_</code>
This actually adds an <tt class="literal"><span class="underline">_init</span>_</tt>
method which always raises a Python RuntimeError exception.
</p>
</div>
@@ -158,8 +158,8 @@
<p>
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"><strong>read-only</strong></span>
or <span class="bold"><strong>read-write</strong></span>. Consider this class <code class="literal">Var</code>:
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">
<span class="keyword">struct</span> <span class="identifier">Var</span>
@@ -170,7 +170,7 @@
<span class="special">};</span>
</pre>
<p>
Our C++ <code class="literal">Var</code> class and its data members can be exposed
Our C++ <tt class="literal">Var</tt> class and its data members can be exposed
to Python:
</p>
<pre class="programlisting">
@@ -191,8 +191,8 @@
<span class="identifier">pi</span> <span class="keyword">is</span> <span class="identifier">around</span> <span class="number">3.14</span>
</pre>
<p>
Note that <code class="literal">name</code> is exposed as <span class="bold"><strong>read-only</strong></span>
while <code class="literal">value</code> is exposed as <span class="bold"><strong>read-write</strong></span>.
Note that <tt class="literal">name</tt> is exposed as <span class="bold"><b>read-only</b></span>
while <tt class="literal">value</tt> is exposed as <span class="bold"><b>read-write</b></span>.
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">'e'</span> <span class="comment"># can't change name
@@ -224,7 +224,7 @@
<p>
However, in Python attribute access is fine; it doesn't neccessarily break
encapsulation to let users handle attributes directly, because the attributes
can just be a different syntax for a method call. Wrapping our <code class="literal">Num</code>
can just be a different syntax for a method call. Wrapping our <tt class="literal">Num</tt>
class using Boost.Python:
</p>
<pre class="programlisting">
@@ -245,8 +245,8 @@
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span> <span class="special">=</span> <span class="number">2.17</span> <span class="comment"># error!
</span></pre>
<p>
Take note that the class property <code class="literal">rovalue</code> is exposed as
<span class="bold"><strong>read-only</strong></span> since the <code class="literal">rovalue</code>
Take note that the class property <tt class="literal">rovalue</tt> is exposed as
<span class="bold"><b>read-only</b></span> since the <tt class="literal">rovalue</tt>
setter member function is not passed in:
</p>
<p>
@@ -273,7 +273,7 @@
<span class="keyword">struct</span> <span class="identifier">Derived</span> <span class="special">:</span> <span class="identifier">Base</span> <span class="special">{};</span>
</pre>
<p>
And a set of C++ functions operating on <code class="literal">Base</code> and <code class="literal">Derived</code>
And a set of C++ functions operating on <tt class="literal">Base</tt> and <tt class="literal">Derived</tt>
object instances:
</p>
<pre class="programlisting">
@@ -282,7 +282,7 @@
<span class="identifier">Base</span><span class="special">*</span> <span class="identifier">factory</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">Derived</span><span class="special">;</span> <span class="special">}</span>
</pre>
<p>
We've seen how we can wrap the base class <code class="literal">Base</code>:
We've seen how we can wrap the base class <tt class="literal">Base</tt>:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
@@ -290,8 +290,8 @@
<span class="special">;</span>
</pre>
<p>
Now we can inform Boost.Python of the inheritance relationship between <code class="literal">Derived</code>
and its base class <code class="literal">Base</code>. Thus:
Now we can inform Boost.Python of the inheritance relationship between <tt class="literal">Derived</tt>
and its base class <tt class="literal">Base</tt>. Thus:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span> <span class="special">&gt;(</span><span class="string">"Derived"</span><span class="special">)</span>
@@ -307,15 +307,15 @@
member functions)
</li>
<li>
<span class="bold"><strong>If</strong></span> Base is polymorphic, <code class="literal">Derived</code>
<span class="bold"><b>If</b></span> Base is polymorphic, <tt class="literal">Derived</tt>
objects which have been passed to Python via a pointer or reference to
<code class="literal">Base</code> can be passed where a pointer or reference to
<code class="literal">Derived</code> is expected.
<tt class="literal">Base</tt> can be passed where a pointer or reference to
<tt class="literal">Derived</tt> is expected.
</li>
</ol></div>
<p>
Now, we shall expose the C++ free functions <code class="literal">b</code> and <code class="literal">d</code>
and <code class="literal">factory</code>:
Now, we will expose the C++ free functions <tt class="literal">b</tt> and <tt class="literal">d</tt>
and <tt class="literal">factory</tt>:
</p>
<pre class="programlisting">
<span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
@@ -323,12 +323,12 @@
<span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">);</span>
</pre>
<p>
Note that free function <code class="literal">factory</code> is being used to generate
new instances of class <code class="literal">Derived</code>. In such cases, we use
<code class="literal">return_value_policy&lt;manage_new_object&gt;</code> to instruct
Python to adopt the pointer to <code class="literal">Base</code> and hold the instance
in a new Python <code class="literal">Base</code> object until the the Python object
is destroyed. We shall see more of Boost.Python <a href="functions.html#python.call_policies" title="Call Policies">call
Note that free function <tt class="literal">factory</tt> is being used to generate
new instances of class <tt class="literal">Derived</tt>. In such cases, we use
<tt class="literal">return_value_policy&lt;manage_new_object&gt;</tt> to instruct
Python to adopt the pointer to <tt class="literal">Base</tt> and hold the instance
in a new Python <tt class="literal">Base</tt> object until the the Python object
is destroyed. We will see more of Boost.Python <a href="functions.html#python.call_policies" title="Call Policies">call
policies</a> later.
</p>
<pre class="programlisting">
@@ -341,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>
In this section, we shall learn how to make functions behave polymorphically
In this section, we will learn how to make functions behave polymorphically
through virtual functions. Continuing our example, let us add a virtual function
to our <code class="literal">Base</code> class:
to our <tt class="literal">Base</tt> class:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span>
@@ -356,11 +356,11 @@
One of the goals of Boost.Python is to be minimally intrusive on an existing
C++ design. In principle, it should be possible to expose the interface for
a 3rd party library without changing it. It is not ideal to add anything
to our class <code class="computeroutput"><span class="identifier">Base</span></code>. Yet, when
to our class <tt class="computeroutput"><span class="identifier">Base</span></tt>. Yet, when
you have a virtual function that's going to be overridden in Python and called
polymorphically <span class="bold"><strong>from C++</strong></span>, we'll need to
polymorphically <span class="bold"><b>from C++</b></span>, we'll need to
add some scaffoldings to make things work properly. What we'll do is write
a class wrapper that derives from <code class="computeroutput"><span class="identifier">Base</span></code>
a class wrapper that derives from <tt class="computeroutput"><span class="identifier">Base</span></tt>
that will unintrusively hook into the virtual functions so that a Python
override may be called:
</p>
@@ -374,25 +374,28 @@
<span class="special">};</span>
</pre>
<p>
Notice too that in addition to inheriting from <code class="computeroutput"><span class="identifier">Base</span></code>,
we also multiply- inherited <code class="computeroutput"><span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span></code> (See <a href="../../../../v2/wrapper.html" target="_top">Wrapper</a>).
The <code class="computeroutput"><span class="identifier">wrapper</span></code> template makes
Notice too that in addition to inheriting from <tt class="computeroutput"><span class="identifier">Base</span></tt>,
we also multiply- inherited <tt class="computeroutput"><span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span></tt> (See <a href="../../../../v2/wrapper.html" target="_top">Wrapper</a>).
The <tt class="computeroutput"><span class="identifier">wrapper</span></tt> template makes
the job of wrapping classes that are meant to overridden in Python, easier.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to write <code class="computeroutput"><span class="identifier">f</span></code> as:<br> <br> <code class="computeroutput"><span class="keyword">return</span>
<span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="keyword">this</span><span class="special">-&gt;</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></code>.
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span>
</p>
<p>
If you are using Microsoft Visual C++ 6 or 7, you have to write <tt class="computeroutput"><span class="identifier">f</span></tt> as:
</p>
<p>
<tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="keyword">this</span><span class="special">-&gt;</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>.
</p>
</div>
<p>
BaseWrap's overridden virtual member function <code class="computeroutput"><span class="identifier">f</span></code>
in effect calls the corresponding method of the Python object through <code class="computeroutput"><span class="identifier">get_override</span></code>.
BaseWrap's overridden virtual member function <tt class="computeroutput"><span class="identifier">f</span></tt>
in effect calls the corresponding method of the Python object through <tt class="computeroutput"><span class="identifier">get_override</span></tt>.
</p>
<p>
Finally, exposing <code class="computeroutput"><span class="identifier">Base</span></code>:
Finally, exposing <tt class="computeroutput"><span class="identifier">Base</span></tt>:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
@@ -400,17 +403,25 @@
<span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">pure_virtual</span></code> signals Boost.Python
that the function <code class="computeroutput"><span class="identifier">f</span></code> is a
<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="sidebar">
<p class="title"><b></b></p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td colspan="2" align="left" valign="top">
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>member function and methods</strong></span><br>
<br> Python, like many object oriented languages uses the term <span class="bold"><strong>methods</strong></span>. Methods correspond roughly to C++'s <span class="bold"><strong>member functions</strong></span>
</p>
</div>
<span class="bold"><b>member function and methods</b></span>
</p>
<p>
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>
</p>
</td></tr>
</table></div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
@@ -418,7 +429,7 @@
<p>
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"><strong>non</strong></span>-pure-virtual
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>
@@ -433,8 +444,8 @@
<span class="special">};</span>
</pre>
<p>
had a pure virtual function <code class="literal">f</code>. If, however, its member
function <code class="literal">f</code> was not declared as pure virtual:
had a pure virtual function <tt class="literal">f</tt>. If, however, its member
function <tt class="literal">f</tt> was not declared as pure virtual:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span>
@@ -460,17 +471,20 @@
<span class="special">};</span>
</pre>
<p>
Notice how we implemented <code class="computeroutput"><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">f</span></code>. Now,
we have to check if there is an override for <code class="computeroutput"><span class="identifier">f</span></code>.
If none, then we call <code class="computeroutput"><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">()</span></code>.
Notice how we implemented <tt class="computeroutput"><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">f</span></tt>. Now,
we have to check if there is an override for <tt class="computeroutput"><span class="identifier">f</span></tt>.
If none, then we call <tt class="computeroutput"><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">()</span></tt>.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to rewrite
the line with the <code class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></code> as:<br> <br> <code class="computeroutput"><span class="keyword">return</span>
<span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*&gt;(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></code>.
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span>
</p>
<p>
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:
</p>
<p>
<tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*&gt;(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></tt>.
</p>
</div>
<p>
@@ -482,10 +496,10 @@
<span class="special">;</span>
</pre>
<p>
Take note that we expose both <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span></code> and <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span></code>. Boost.Python needs to keep track
of 1) the dispatch function <code class="literal">f</code> and 2) the forwarding function
to its default implementation <code class="literal">default_f</code>. There's a special
<code class="literal">def</code> function for this purpose.
Take note that we expose both <tt class="computeroutput"><span class="special">&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span></tt> and <tt class="computeroutput"><span class="special">&amp;</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span></tt>. Boost.Python needs to keep track
of 1) the dispatch function <tt class="literal">f</tt> and 2) the forwarding function
to its default implementation <tt class="literal">default_f</tt>. There's a special
<tt class="literal">def</tt> function for this purpose.
</p>
<p>
In Python, the results would be as expected:
@@ -501,14 +515,14 @@
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">derived</span> <span class="special">=</span> <span class="identifier">Derived</span><span class="special">()</span>
</pre>
<p>
Calling <code class="literal">base.f()</code>:
Calling <tt class="literal">base.f()</tt>:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">base</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
<span class="number">0</span>
</pre>
<p>
Calling <code class="literal">derived.f()</code>:
Calling <tt class="literal">derived.f()</tt>:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">derived</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
@@ -518,17 +532,17 @@
<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.python_operators"></a><h3>
<a name="id2646169"></a>
<a name="class_operators_special_functions.python_operators"></a><h2>
<a name="id461377"></a>
Python Operators
</h3>
</h2>
<p>
C is well known for the abundance of operators. C++ extends this to the extremes
by allowing operator overloading. Boost.Python takes advantage of this and
makes it easy to wrap C++ operator-powered classes.
</p>
<p>
Consider a file position class <code class="literal">FilePos</code> and a set of operators
Consider a file position class <tt class="literal">FilePos</tt> and a set of operators
that take on FilePos instances:
</p>
<p>
@@ -561,16 +575,16 @@
<p>
The code snippet above is very clear and needs almost no explanation at all.
It is virtually the same as the operators' signatures. Just take note that
<code class="literal">self</code> refers to FilePos object. Also, not every class
<code class="literal">T</code> that you might need to interact with in an operator
expression is (cheaply) default-constructible. You can use <code class="literal">other&lt;T&gt;()</code>
in place of an actual <code class="literal">T</code> instance when writing "self
<tt class="literal">self</tt> refers to FilePos object. Also, not every class
<tt class="literal">T</tt> that you might need to interact with in an operator
expression is (cheaply) default-constructible. You can use <tt class="literal">other&lt;T&gt;()</tt>
in place of an actual <tt class="literal">T</tt> instance when writing "self
expressions".
</p>
<a name="class_operators_special_functions.special_methods"></a><h3>
<a name="id2646853"></a>
<a name="class_operators_special_functions.special_methods"></a><h2>
<a name="id462134"></a>
Special Methods
</h3>
</h2>
<p>
Python has a few more <span class="emphasis"><em>Special Methods</em></span>. Boost.Python
supports all of the standard special method names supported by real Python
@@ -596,15 +610,16 @@
<p>
Need we say more?
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> What is the business of <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>? Well, the method <code class="computeroutput"><span class="identifier">str</span></code>
requires the <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>
to do its work (i.e. <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code> is used by the method defined by
<code 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></code>.
</p>
</div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td colspan="2" align="left" valign="top"><p>
What is the business of <tt class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</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">&lt;&lt;</span></tt> to do its work (i.e. <tt class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</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>.
</p></td></tr>
</table></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
@@ -614,7 +629,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="hello.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="hello.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -3,24 +3,24 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Functions</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="exposing.html" title="Exposing Classes">
<link rel="next" href="object.html" title="Object Interface">
<link rel="prev" href="exposing.html" title=" Exposing Classes">
<link rel="next" href="object.html" title=" Object Interface">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<table cellpadding="2" width="100%"><tr>
<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>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</table>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="exposing.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="exposing.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@@ -33,10 +33,10 @@
</dl></div>
<p>
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.
We will see some facilities to make exposing C++ functions to Python safe from
potential pifalls such as dangling pointers and references. We will 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>
@@ -49,7 +49,7 @@
</blockquote></div>
<p>
But before you do, you might want to fire up Python 2.2 or later and type
<code class="literal">&gt;&gt;&gt; import this</code>.
<tt class="literal">&gt;&gt;&gt; import this</tt>.
</p>
<pre class="programlisting">&gt;&gt;&gt; import this
The Zen of Python, by Tim Peters
@@ -68,7 +68,7 @@ In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than <span class="bold"><strong>right</strong></span> now.
Although never is often better than <span class="bold"><b>right</b></span> now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
@@ -126,19 +126,19 @@ Namespaces are one honking great idea -- let's do more of those!
</p>
<div class="orderedlist"><ol type="1">
<li>
<code class="literal">f</code> is called passing in a reference to <code class="literal">y</code>
and a pointer to <code class="literal">z</code>
<tt class="literal">f</tt> is called passing in a reference to <tt class="literal">y</tt>
and a pointer to <tt class="literal">z</tt>
</li>
<li>
A reference to <code class="literal">y.x</code> is returned
A reference to <tt class="literal">y.x</tt> is returned
</li>
<li>
<code class="literal">y</code> is deleted. <code class="literal">x</code> is a dangling reference
<tt class="literal">y</tt> is deleted. <tt class="literal">x</tt> is a dangling reference
</li>
<li>
<code class="literal">x.some_method()</code> is called
<tt class="literal">x.some_method()</tt> is called
</li>
<li><span class="bold"><strong>BOOM!</strong></span></li>
<li><span class="bold"><b>BOOM!</b></span></li>
</ol></div>
<p>
We could copy result into a new object:
@@ -168,7 +168,7 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="special">};</span>
</pre>
<p>
Notice that the data member <code class="literal">z</code> is held by class Y using
Notice that the data member <tt class="literal">z</tt> is held by class Y using
a raw pointer. Now we have a potential dangling pointer problem inside Y:
</p>
<pre class="programlisting">
@@ -177,7 +177,7 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
</pre>
<p>
For reference, here's the implementation of <code class="literal">f</code> again:
For reference, here's the implementation of <tt class="literal">f</tt> again:
</p>
<pre class="programlisting">
<span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</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>
@@ -191,33 +191,33 @@ Namespaces are one honking great idea -- let's do more of those!
</p>
<div class="orderedlist"><ol type="1">
<li>
<code class="literal">f</code> is called passing in a reference to <code class="literal">y</code>
and a pointer to <code class="literal">z</code>
<tt class="literal">f</tt> is called passing in a reference to <tt class="literal">y</tt>
and a pointer to <tt class="literal">z</tt>
</li>
<li>
A pointer to <code class="literal">z</code> is held by <code class="literal">y</code>
A pointer to <tt class="literal">z</tt> is held by <tt class="literal">y</tt>
</li>
<li>
A reference to <code class="literal">y.x</code> is returned
A reference to <tt class="literal">y.x</tt> is returned
</li>
<li>
<code class="literal">z</code> is deleted. <code class="literal">y.z</code> is a dangling pointer
<tt class="literal">z</tt> is deleted. <tt class="literal">y.z</tt> is a dangling pointer
</li>
<li>
<code class="literal">y.z_value()</code> is called
<tt class="literal">y.z_value()</tt> is called
</li>
<li>
<code class="literal">z-&gt;value()</code> is called
<tt class="literal">z-&gt;value()</tt> is called
</li>
<li><span class="bold"><strong>BOOM!</strong></span></li>
<li><span class="bold"><b>BOOM!</b></span></li>
</ol></div>
<a name="call_policies.call_policies"></a><h3>
<a name="id2648560"></a>
<a name="call_policies.call_policies"></a><h2>
<a name="id463996"></a>
Call Policies
</h3>
</h2>
<p>
Call Policies may be used in situations such as the example detailed above.
In our example, <code class="literal">return_internal_reference</code> and <code class="literal">with_custodian_and_ward</code>
In our example, <tt class="literal">return_internal_reference</tt> and <tt class="literal">with_custodian_and_ward</tt>
are our friends:
</p>
<pre class="programlisting">
@@ -226,27 +226,27 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="identifier">with_custodian_and_ward</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span> <span class="special">&gt;());</span>
</pre>
<p>
What are the <code class="literal">1</code> and <code class="literal">2</code> parameters, you
What are the <tt class="literal">1</tt> and <tt class="literal">2</tt> parameters, you
ask?
</p>
<pre class="programlisting">
<span class="identifier">return_internal_reference</span><span class="special">&lt;</span><span class="number">1</span>
</pre>
<p>
Informs Boost.Python that the first argument, in our case <code class="literal">Y&amp;
y</code>, is the owner of the returned reference: <code class="literal">X&amp;</code>.
The "<code class="literal">1</code>" simply specifies the first argument.
In short: "return an internal reference <code class="literal">X&amp;</code> owned
by the 1st argument <code class="literal">Y&amp; y</code>".
Informs Boost.Python that the first argument, in our case <tt class="literal">Y&amp;
y</tt>, is the owner of the returned reference: <tt class="literal">X&amp;</tt>.
The "<tt class="literal">1</tt>" simply specifies the first argument.
In short: "return an internal reference <tt class="literal">X&amp;</tt> owned
by the 1st argument <tt class="literal">Y&amp; y</tt>".
</p>
<pre class="programlisting">
<span class="identifier">with_custodian_and_ward</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span>
</pre>
<p>
Informs Boost.Python that the lifetime of the argument indicated by ward
(i.e. the 2nd argument: <code class="literal">Z* z</code>) is dependent on the lifetime
of the argument indicated by custodian (i.e. the 1st argument: <code class="literal">Y&amp;
y</code>).
(i.e. the 2nd argument: <tt class="literal">Z* z</tt>) is dependent on the lifetime
of the argument indicated by custodian (i.e. the 1st argument: <tt class="literal">Y&amp;
y</tt>).
</p>
<p>
It is also important to note that we have defined two policies above. Two
@@ -263,42 +263,46 @@ Namespaces are one honking great idea -- let's do more of those!
</p>
<div class="itemizedlist"><ul type="disc">
<li>
<span class="bold"><strong>with_custodian_and_ward</strong></span><br> Ties lifetimes
<span class="bold"><b>with_custodian_and_ward</b></span>: Ties lifetimes
of the arguments
</li>
<li>
<span class="bold"><strong>with_custodian_and_ward_postcall</strong></span><br>
Ties lifetimes of the arguments and results
<span class="bold"><b>with_custodian_and_ward_postcall</b></span>: Ties
lifetimes of the arguments and results
</li>
<li>
<span class="bold"><strong>return_internal_reference</strong></span><br> Ties lifetime
<span class="bold"><b>return_internal_reference</b></span>: Ties lifetime
of one argument to that of result
</li>
<li>
<span class="bold"><strong>return_value_policy&lt;T&gt; with T one of:</strong></span><br>
<span class="bold"><b>return_value_policy&lt;T&gt; with T one of:</b></span><div class="itemizedlist"><ul type="circle">
<li>
<span class="bold"><b>reference_existing_object</b></span>: naive (dangerous)
approach
</li>
<li>
<span class="bold"><b>copy_const_reference</b></span>: Boost.Python
v1 approach
</li>
<li>
<span class="bold"><b>copy_non_const_reference</b></span>:
</li>
<li>
<span class="bold"><b>manage_new_object</b></span>: Adopt a pointer
and hold the instance
</li>
</ul></div>
</li>
<li>
<span class="bold"><strong>reference_existing_object</strong></span><br> naive
(dangerous) approach
</li>
<li>
<span class="bold"><strong>copy_const_reference</strong></span><br> Boost.Python
v1 approach
</li>
<li>
<span class="bold"><strong>copy_non_const_reference</strong></span><br>
</li>
<li>
<span class="bold"><strong>manage_new_object</strong></span><br> Adopt a pointer
and hold the instance
</li>
</ul></div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><strong>Remember the Zen, Luke:</strong></span><br>
<br> "Explicit is better than implicit"<br> "In the face
of ambiguity, refuse the temptation to guess"<br>
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><b>Remember the Zen, Luke:</b></span>
</p>
<p>
"Explicit is better than implicit"
</p>
<p>
"In the face of ambiguity, refuse the temptation to guess"
</p>
</div>
</div>
@@ -338,7 +342,7 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="special">};</span>
</pre>
<p>
Class X has 4 overloaded functions. We shall start by introducing some member
Class X has 4 overloaded functions. We will start by introducing some member
function pointer variables:
</p>
<pre class="programlisting">
@@ -362,21 +366,21 @@ Namespaces are one honking great idea -- let's do more of those!
<a name="python.default_arguments"></a>Default Arguments</h3></div></div></div>
<p>
Boost.Python wraps (member) function pointers. Unfortunately, C++ function
pointers carry no default argument info. Take a function <code class="literal">f</code>
pointers carry no default argument info. Take a function <tt class="literal">f</tt>
with default arguments:
</p>
<pre class="programlisting">
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="special">=</span> <span class="string">"hello"</span><span class="special">);</span>
</pre>
<p>
But the type of a pointer to the function <code class="literal">f</code> has no information
But the type of a pointer to the function <tt class="literal">f</tt> has no information
about its default arguments:
</p>
<pre class="programlisting">
<span class="keyword">int</span><span class="special">(*</span><span class="identifier">g</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*)</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span> <span class="comment">// defaults lost!
</span></pre>
<p>
When we pass this function pointer to the <code class="literal">def</code> function,
When we pass this function pointer to the <tt class="literal">def</tt> function,
there is no way to retrieve the default arguments:
</p>
<pre class="programlisting">
@@ -410,10 +414,10 @@ Namespaces are one honking great idea -- let's do more of those!
are overloaded with a common sequence of initial arguments
</li>
</ul></div>
<a name="default_arguments.boost_python_function_overloads"></a><h3>
<a name="id2650414"></a>
<a name="default_arguments.boost_python_function_overloads"></a><h2>
<a name="id466035"></a>
BOOST_PYTHON_FUNCTION_OVERLOADS
</h3>
</h2>
<p>
Boost.Python now has a way to make it easier. For instance, given a function:
</p>
@@ -431,19 +435,19 @@ Namespaces are one honking great idea -- let's do more of those!
</pre>
<p>
will automatically create the thin wrappers for us. This macro will create
a class <code class="literal">foo_overloads</code> that can be passed on to <code class="literal">def(...)</code>.
a class <tt class="literal">foo_overloads</tt> that can be passed on to <tt class="literal">def(...)</tt>.
The third and fourth macro argument are the minimum arguments and maximum
arguments, respectively. In our <code class="literal">foo</code> function the minimum
number of arguments is 1 and the maximum number of arguments is 4. The <code class="literal">def(...)</code>
arguments, respectively. In our <tt class="literal">foo</tt> function the minimum
number of arguments is 1 and the maximum number of arguments is 4. The <tt class="literal">def(...)</tt>
function will automatically add all the foo variants for us:
</p>
<pre class="programlisting">
<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><h3>
<a name="id2650701"></a>
<a name="default_arguments.boost_python_member_function_overloads"></a><h2>
<a name="id466353"></a>
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
</h3>
</h2>
<p>
Objects here, objects there, objects here there everywhere. More frequently
than anything else, we need to expose member functions of our classes to
@@ -452,7 +456,7 @@ Namespaces are one honking great idea -- let's do more of those!
play. Another macro is provided to make this a breeze.
</p>
<p>
Like <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>, <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
Like <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>, <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
may be used to automatically create the thin wrappers for wrapping member
functions. Let's have an example:
</p>
@@ -473,11 +477,11 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">george_overloads</span><span class="special">,</span> <span class="identifier">wack_em</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
</pre>
<p>
will generate a set of thin wrappers for george's <code class="literal">wack_em</code>
will generate a set of thin wrappers for george's <tt class="literal">wack_em</tt>
member function accepting a minimum of 1 and a maximum of 3 arguments (i.e.
the third and fourth macro argument). The thin wrappers are all enclosed
in a class named <code class="literal">george_overloads</code> that can then be used
as an argument to <code class="literal">def(...)</code>:
in a class named <tt class="literal">george_overloads</tt> that can then be used
as an argument to <tt class="literal">def(...)</tt>:
</p>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">george</span><span class="special">::</span><span class="identifier">wack_em</span><span class="special">,</span> <span class="identifier">george_overloads</span><span class="special">());</span>
@@ -486,13 +490,13 @@ Namespaces are one honking great idea -- let's do more of those!
See the <a href="../../../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec" target="_top">overloads
reference</a> for details.
</p>
<a name="default_arguments.init_and_optional"></a><h3>
<a name="id2651031"></a>
<a name="default_arguments.init_and_optional"></a><h2>
<a name="id466716"></a>
init and optional
</h3>
</h2>
<p>
A similar facility is provided for class constructors, again, with default
arguments or a sequence of overloads. Remember <code class="literal">init&lt;...&gt;</code>?
arguments or a sequence of overloads. Remember <tt class="literal">init&lt;...&gt;</tt>?
For example, given a class X with a constructor:
</p>
<pre class="programlisting">
@@ -509,7 +513,7 @@ Namespaces are one honking great idea -- let's do more of those!
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="special">&gt;())</span>
</pre>
<p>
Notice the use of <code class="literal">init&lt;...&gt;</code> and <code class="literal">optional&lt;...&gt;</code>
Notice the use of <tt class="literal">init&lt;...&gt;</tt> and <tt class="literal">optional&lt;...&gt;</tt>
to signify the default (optional arguments).
</p>
</div>
@@ -517,8 +521,8 @@ 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>
It was mentioned in passing in the previous section that <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>
and <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code> can also be
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>
@@ -560,24 +564,24 @@ Namespaces are one honking great idea -- let's do more of those!
Notice though that we have a situation now where we have a minimum of zero
(0) arguments and a maximum of 3 arguments.
</p>
<a name="auto_overloading.manual_wrapping"></a><h3>
<a name="id2651734"></a>
<a name="auto_overloading.manual_wrapping"></a><h2>
<a name="id467498"></a>
Manual Wrapping
</h3>
</h2>
<p>
It is important to emphasize however that <span class="bold"><strong>the overloaded
functions must have a common sequence of initial arguments</strong></span>. Otherwise,
It is important to emphasize however that <span class="bold"><b>the overloaded
functions must have a common sequence of initial arguments</b></span>. Otherwise,
our scheme above will not work. If this is not the case, we have to wrap
our functions <a href="functions.html#python.overloading" title="Overloading">manually</a>.
</p>
<p>
Actually, we can mix and match manual wrapping of overloaded functions and
automatic wrapping through <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
and its sister, <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>. Following
automatic wrapping through <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
and its sister, <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>. Following
up on our example presented in the section <a href="functions.html#python.overloading" title="Overloading">on
overloading</a>, since the first 4 overload functins have a common sequence
of initial arguments, we can use <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
to automatically wrap the first three of the <code class="literal">def</code>s and
of initial arguments, we can use <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
to automatically wrap the first three of the <tt class="literal">def</tt>s and
manually wrap just the last. Here's how we'll do this:
</p>
<pre class="programlisting">
@@ -606,7 +610,7 @@ Namespaces are one honking great idea -- let's do more of those!
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="exposing.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="exposing.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -1,84 +1,71 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Building Hello World</title>
<title> Building Hello World</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="../index.html" title="Chapter 1. python 1.0">
<link rel="next" href="exposing.html" title="Exposing Classes">
<link rel="next" href="exposing.html" title=" Exposing Classes">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<table cellpadding="2" width="100%"><tr>
<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>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</table>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="../index.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<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.from_start_to_finish"></a><h3>
<a name="id2595436"></a>
<a name="hello.from_start_to_finish"></a><h2>
<a name="id386086"></a>
From Start To Finish
</h3>
</h2>
<p>
Now the first thing you'd want to do is to build the Hello World module and
try it for yourself in Python. In this section, we shall outline the steps
necessary to achieve that. We shall use the build tool that comes bundled with
every boost distribution: <span class="bold"><strong>bjam</strong></span>.
try it for yourself in Python. In this section, we will outline the steps necessary
to achieve that. We will use the build tool that comes bundled with every boost
distribution: <span class="bold"><b>bjam</b></span>.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td colspan="2" align="left" valign="top">
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>Building without bjam</strong></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 <code class="literal">bjam</code>.<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.
</p>
</div>
<span class="bold"><b>Building without bjam</b></span>
</p>
<p>
We shall skip over the details. Our objective will be to simply create the
hello world module and run it in Python. For a complete reference to building
Boost.Python, check out: <a href="../../../../building.html" target="_top">building.html</a>.
After this brief <span class="emphasis"><em>bjam</em></span> tutorial, we should have built two
DLLs:
</p>
<div class="itemizedlist"><ul type="disc">
<li>
boost_python.dll
</li>
<li>
hello.pyd
</li>
</ul></div>
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>.
</p>
<p>
if you are on Windows, and
</p>
<div class="itemizedlist"><ul type="disc">
<li>
libboost_python.so
</li>
<li>
hello.so
</li>
</ul></div>
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.
</p>
</td></tr>
</table></div>
<p>
if you are on Unix.
We will skip over the details. Our objective will be to simply create the hello
world module and run it in Python. For a complete reference to building Boost.Python,
check out: <a href="../../../../building.html" target="_top">building.html</a>. After
this brief <span class="emphasis"><em>bjam</em></span> tutorial, we should have built the DLLs
and run a python program using the extension.
</p>
<p>
The tutorial example can be found in the directory: <code class="literal">libs/python/example/tutorial</code>.
The tutorial example can be found in the directory: <tt class="literal">libs/python/example/tutorial</tt>.
There, you can find:
</p>
<div class="itemizedlist"><ul type="disc">
@@ -86,75 +73,44 @@
hello.cpp
</li>
<li>
Jamfile
hello.py
</li>
<li>
Jamroot
</li>
</ul></div>
<p>
The <code class="literal">hello.cpp</code> file is our C++ hello world example. The
<code class="literal">Jamfile</code> is a minimalist <span class="emphasis"><em>bjam</em></span> script
that builds the DLLs for us.
The <tt class="literal">hello.cpp</tt> file is our C++ hello world example. The
<tt class="literal">Jamroot</tt> is a minimalist <span class="emphasis"><em>bjam</em></span> script
that builds the DLLs for us. Finally, <tt class="literal">hello.py</tt> is our Python
program that uses the extension in <tt class="literal">hello.cpp</tt>.
</p>
<p>
Before anything else, you should have the bjam executable in your boost directory
or somewhere in your path such that <code class="literal">bjam</code> can be executed
or somewhere in your path such that <tt class="literal">bjam</tt> can be executed
in the command line. Pre-built Boost.Jam executables are available for most
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><h3>
<a name="id2595623"></a>
<a name="hello.let_s_jam_"></a><h2>
<a name="id386244"></a>
Let's Jam!
</h3>
</h2>
<p>
<span class="inlinemediaobject"><img src="../images/jam.png" alt="jam"></span>
</p>
<p>
Here is our minimalist Jamfile:
</p>
<pre class="programlisting"># This is the top of our own project tree
project-root ;
import python ;
extension hello # Declare a Python extension called hello
: hello.cpp # source
# requirements and dependencies for Boost.Python extensions
&lt;template&gt;@boost/libs/python/build/extension
;
</pre>
<p>
First, we need to specify our location. You may place your project anywhere.
<code class="literal">project-root</code> allows you to do that.
</p>
<pre class="programlisting">project-root ;
</pre>
<p>
By doing so, you'll need a Jamrules file. Simply copy the one in the <a href="../../../../../example/tutorial/Jamrules" target="_top">example/tutorial directory</a>
and tweak the <code class="literal">path-global BOOST_ROOT</code> to where your boost
root directory is. The file has <a href="../../../../../example/tutorial/Jamrules" target="_top">detailed
instructions</a> you can follow.
<a href="../../../../../example/tutorial/Jamroot" target="_top">Here</a> is our minimalist
Jamroot file. Simply copy the file and tweak <tt class="literal">use-project boost</tt>
to where your boost root directory is and your OK.
</p>
<p>
Then we will import the definitions needed by Python modules:
The comments contained in the Jamrules file above should be sufficient to get
you going.
</p>
<pre class="programlisting">import python ;
</pre>
<p>
Finally we declare our <code class="literal">hello</code> extension:
</p>
<pre class="programlisting">extension hello # Declare a Python extension called hello
: hello.cpp # source
# requirements and dependencies for Boost.Python extensions
&lt;template&gt;@boost/libs/python/build/extension
;
</pre>
<p>
The last part tells BJam that we are depending on the Boost Python Library.
</p>
<a name="hello.running_bjam"></a><h3>
<a name="id2595752"></a>
<a name="hello.running_bjam"></a><h2>
<a name="id386301"></a>
Running bjam
</h3>
</h2>
<p>
<span class="emphasis"><em>bjam</em></span> is run using your operating system's command line
interpreter.
@@ -169,124 +125,66 @@ extension hello # Declare a Python extension called hello
</p>
</blockquote></div>
<p>
Make sure that the environment is set so that we can invoke the C++ compiler.
With MSVC, that would mean running the <code class="literal">Vcvars32.bat</code> batch
file. For instance:
A file called user-config.jam in your home directory is used to configure your
tools. In Windows, your home directory can be found by typing:
</p>
<pre class="programlisting">C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat
<pre class="programlisting">ECHO %HOMEDRIVE%%HOMEPATH%
</pre>
<p>
Some environment variables will have to be setup for proper building of our
Python modules. Example:
into a command prompt window. Your file should at least have the rules for
your compiler and your python installation. A specific example of this on Windows
would be:
</p>
<pre class="programlisting">set PYTHON_ROOT=c:/dev/tools/python
set PYTHON_VERSION=2.2
<pre class="programlisting"># MSVC configuration
using msvc : 8.0 ;
# Python configuration
using python : 2.4 : C:/dev/tools<span class="emphasis"><em>Python</em></span> ;
</pre>
<p>
The above assumes that the Python installation is in <code class="literal">c:/dev/tools/python</code>
and that we are using Python version 2.2. You'll have to tweak these appropriately.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> Be sure not to include a third number, e.g. <span class="bold"><strong>not</strong></span> "2.2.1", even if that's the version you
have.
</p>
</div>
<p>
Take note that you may also do that through the Jamrules file we put in our
project as detailed above. The file has <a href="../../../../../example/tutorial/Jamrules" target="_top">detailed
instructions</a> you can follow.
The first rule tells Bjam to use the MSVC 8.0 compiler and associated tools.
The second rule provides information on Python, its version and where it is
located. The above assumes that the Python installation is in <tt class="literal">C:/dev/tools/Python/</tt>.
If you have one fairly "standard" python installation for your platform,
you might not need to do this.
</p>
<p>
Now we are ready... Be sure to <code class="literal">cd</code> to <code class="literal">libs/python/example/tutorial</code>
where the tutorial <code class="literal">"hello.cpp"</code> and the <code class="literal">"Jamfile"</code>
Now we are ready... Be sure to <tt class="literal">cd</tt> to <tt class="literal">libs/python/example/tutorial</tt>
where the tutorial <tt class="literal">"hello.cpp"</tt> and the <tt class="literal">"Jamroot"</tt>
is situated.
</p>
<p>
Finally:
</p>
<pre class="programlisting">
<span class="identifier">bjam</span> <span class="special">-</span><span class="identifier">sTOOLS</span><span class="special">=</span><span class="identifier">vc</span><span class="special">-</span><span class="number">7</span><span class="identifier">_1</span>
<span class="identifier">bjam</span>
</pre>
<p>
We are again assuming that we are using Microsoft Visual C++ version 7.1. If
not, then you will have to specify the appropriate tool. See <a href="../../../../../../../tools/build/index.html" target="_top">Building
Boost Libraries</a> for further details.
</p>
<p>
It should be building now:
</p>
<pre class="programlisting">cd C:\dev\boost\libs\python\example\tutorial
bjam -sTOOLS=msvc
bjam
...patience...
...found 1703 targets...
...updating 40 targets...
...found 1101 targets...
...updating 35 targets...
</pre>
<p>
And so on... Finally:
</p>
<pre class="programlisting">Creating library bin\boost\libs\python\build\boost_python.dll\vc-7_1\debug\th
reading-multi\boost_python.lib and object bin\boost\libs\python\build\boost_pyth
on.dll\vc-7_1\debug\threading-multi\boost_python.exp
vc-C++ bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.obj
hello.cpp
vc-Link bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.pyd bin\tutori
al\hello.pyd\vc-7_1\debug\threading-multi\hello.lib
Creating library bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.li
b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp
...updated 31 targets...
</pre>
<p>
If all is well, you should now have:
</p>
<div class="itemizedlist"><ul type="disc">
<li>
boost_python.dll
</li>
<li>
hello.pyd
</li>
</ul></div>
<p>
if you are on Windows, and
</p>
<div class="itemizedlist"><ul type="disc">
<li>
libboost_python.so
</li>
<li>
hello.so
</li>
</ul></div>
<p>
if you are on Unix.
</p>
<p>
<code class="literal">boost_python.dll</code> and <code class="literal">hello.pyd</code> can be
found somewhere in your project's <code class="literal">bin</code> 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.)
</p>
<p>
You may now fire up Python and run our hello module:
</p>
<p>
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello</span>
<span class="special">&gt;&gt;&gt;</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 class="programlisting">Creating library <span class="emphasis"><em>path-to-boost_python.dll</em></span>
Creating library <span class="emphasis"><em>path-to-'''hello_ext'''.exp</em></span>
**passed** ... hello.test
...updated 35 targets...
</pre>
<p>
Or something similar. If all is well, you should now have built the DLLs and
run the Python program.
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>
</p>
<p>
<span class="bold"><strong>There you go... Have fun!</strong></span>
<span class="bold"><b>There you go... Have fun!</b></span>
</p>
<p>
</p>
@@ -299,7 +197,7 @@ b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="../index.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -3,24 +3,24 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Iterators</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="embedding.html" title="Embedding">
<link rel="next" href="exception.html" title="Exception Translation">
<link rel="next" href="exception.html" title=" Exception Translation">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<table cellpadding="2" width="100%"><tr>
<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>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</table>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="embedding.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="embedding.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@@ -30,7 +30,7 @@
iterators, but these are two very different beasts.
</p>
<p>
<span class="bold"><strong>C++ iterators:</strong></span>
<span class="bold"><b>C++ iterators:</b></span>
</p>
<div class="itemizedlist"><ul type="disc">
<li>
@@ -45,7 +45,7 @@
</li>
</ul></div>
<p>
<span class="bold"><strong>Python Iterators:</strong></span>
<span class="bold"><b>Python Iterators:</b></span>
</p>
<div class="itemizedlist"><ul type="disc">
<li>
@@ -59,8 +59,8 @@
</li>
</ul></div>
<p>
The typical Python iteration protocol: <code class="literal"><span class="bold"><strong>for y
in x...</strong></span></code> is as follows:
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>
@@ -74,7 +74,7 @@
</span></pre>
<p>
Boost.Python provides some mechanisms to make C++ iterators play along nicely
as Python iterators. What we need to do is to produce appropriate <code class="computeroutput"><span class="identifier">__iter__</span></code> function from C++ iterators that
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>
@@ -91,7 +91,7 @@
<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">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;())</span>
</pre>
<p>
<span class="bold"><strong>range</strong></span>
<span class="bold"><b>range</b></span>
</p>
<p>
We can create a Python savvy iterator using the range function:
@@ -119,14 +119,14 @@
</li>
</ul></div>
<p>
<span class="bold"><strong>iterator</strong></span>
<span class="bold"><b>iterator</b></span>
</p>
<div class="itemizedlist"><ul type="disc"><li>
iterator&lt;T, Policies&gt;()
</li></ul></div>
<p>
Given a container <code class="literal">T</code>, iterator is a shortcut that simply
calls <code class="literal">range</code> with &amp;T::begin, &amp;T::end.
Given a container <tt class="literal">T</tt>, iterator is a shortcut that simply
calls <tt class="literal">range</tt> with &amp;T::begin, &amp;T::end.
</p>
<p>
Let's put this into action... Here's an example from some hypothetical bogon
@@ -152,14 +152,14 @@
<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">(&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_begin</span><span class="special">,</span> <span class="special">&amp;</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"><strong>stl_input_iterator</strong></span>
<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
an STL algorithm or use it to initialize an STL container. We need to make
a Python iterator look like an STL iterator. For that, we use <code class="computeroutput"><span class="identifier">stl_input_iterator</span><span class="special">&lt;&gt;</span></code>.
Consider how we might implement a function that exposes <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">assign</span><span class="special">()</span></code> to Python:
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">&lt;&gt;</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">assign</span><span class="special">()</span></tt> to Python:
</p>
<p>
</p>
@@ -178,7 +178,7 @@
</span> <span class="special">;</span>
</pre>
<p>
Now in Python, we can assign any integer sequence to <code class="computeroutput"><span class="identifier">list_int</span></code>
Now in Python, we can assign any integer sequence to <tt class="computeroutput"><span class="identifier">list_int</span></tt>
objects:
</p>
<p>
@@ -195,7 +195,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="embedding.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="embedding.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -1,26 +1,26 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Object Interface</title>
<title> Object Interface</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="functions.html" title="Functions">
<link rel="next" href="embedding.html" title="Embedding">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<table cellpadding="2" width="100%"><tr>
<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>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</table>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="functions.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="functions.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@@ -35,13 +35,13 @@
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 <code class="literal">object</code>. We shall see in this
are just instances of class <tt class="literal">object</tt>. We will 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
mapping between C++ and Python while maintaining the Python feel. Boost.Python
C++ <code class="literal">object</code>s are as close as possible to Python. This should
C++ <tt class="literal">object</tt>s are as close as possible to Python. This should
minimize the learning curve significantly.
</p>
<p>
@@ -51,10 +51,10 @@
<div class="titlepage"><div><div><h3 class="title">
<a name="python.basic_interface"></a>Basic Interface</h3></div></div></div>
<p>
Class <code class="literal">object</code> wraps <code class="literal">PyObject*</code>. All the
intricacies of dealing with <code class="literal">PyObject</code>s such as managing
reference counting are handled by the <code class="literal">object</code> class. C++
object interoperability is seamless. Boost.Python C++ <code class="literal">object</code>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>
@@ -99,7 +99,7 @@
<div class="titlepage"><div><div><h3 class="title">
<a name="python.derived_object_types"></a>Derived Object types</h3></div></div></div>
<p>
Boost.Python comes with a set of derived <code class="literal">object</code> types
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">
@@ -123,32 +123,32 @@
</li>
</ul></div>
<p>
These derived <code class="literal">object</code> types act like real Python types.
These derived <tt class="literal">object</tt> types act like real Python types.
For instance:
</p>
<pre class="programlisting">
<span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==&gt;</span> <span class="string">"1"</span>
</pre>
<p>
Wherever appropriate, a particular derived <code class="literal">object</code> has
corresponding Python type's methods. For instance, <code class="literal">dict</code>
has a <code class="literal">keys()</code> method:
Wherever appropriate, a particular derived <tt class="literal">object</tt> has
corresponding Python type's methods. For instance, <tt class="literal">dict</tt>
has a <tt class="literal">keys()</tt> method:
</p>
<pre class="programlisting">
<span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
</pre>
<p>
<code class="literal">make_tuple</code> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
<tt class="literal">make_tuple</tt> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
Example:
</p>
<pre class="programlisting">
<span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
</pre>
<p>
In C++, when Boost.Python <code class="literal">object</code>s are used as arguments
In C++, when Boost.Python <tt class="literal">object</tt>s are used as arguments
to functions, subtype matching is required. For example, when a function
<code class="literal">f</code>, as declared below, is wrapped, it will only accept
instances of Python's <code class="literal">str</code> type and subtypes.
<tt class="literal">f</tt>, as declared below, is wrapped, it will only accept
instances of Python's <tt class="literal">str</tt> type and subtypes.
</p>
<pre class="programlisting">
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
@@ -172,18 +172,15 @@
<span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
</pre>
<p>
Demonstrates that you can write the C++ equivalent of <code class="literal">"format"
% x,y,z</code> in Python, which is useful since there's no easy way to
Demonstrates that you can write the C++ equivalent of <tt class="literal">"format"
% x,y,z</tt> in Python, which is useful since there's no easy way to
do that in std C++.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>Beware</strong></span> the common pitfall
<div class="sidebar"><p>
<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.
</p>
</div>
</p></div>
<p>
Python:
</p>
@@ -198,12 +195,12 @@
<span class="identifier">dict</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__
</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><h3>
<a name="id2653534"></a>
<a name="derived_object_types.class__lt_t_gt__as_objects"></a><h2>
<a name="id469503"></a>
class_&lt;T&gt; as objects
</h3>
</h2>
<p>
Due to the dynamic nature of Boost.Python objects, any <code class="literal">class_&lt;T&gt;</code>
Due to the dynamic nature of Boost.Python objects, any <tt class="literal">class_&lt;T&gt;</tt>
may also be one of these types! The following code snippet wraps the class
(type) object.
</p>
@@ -225,15 +222,15 @@
<a name="python.extracting_c___objects"></a>Extracting C++ objects</h3></div></div></div>
<p>
At some point, we will need to get C++ values out of object instances. This
can be achieved with the <code class="literal">extract&lt;T&gt;</code> function. Consider
can be achieved with the <tt class="literal">extract&lt;T&gt;</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
</span></pre>
<p>
In the code above, we got a compiler error because Boost.Python <code class="literal">object</code>
can't be implicitly converted to <code class="literal">double</code>s. Instead, what
In the code above, we got a compiler error because Boost.Python <tt class="literal">object</tt>
can't be implicitly converted to <tt class="literal">double</tt>s. Instead, what
we wanted to do above can be achieved by writing:
</p>
<pre class="programlisting">
@@ -243,14 +240,14 @@
</pre>
<p>
The first line attempts to extract the "length" attribute of the
Boost.Python <code class="literal">object</code>. The second line attempts to <span class="emphasis"><em>extract</em></span>
the <code class="literal">Vec2</code> object from held by the Boost.Python <code class="literal">object</code>.
Boost.Python <tt class="literal">object</tt>. The second line attempts to <span class="emphasis"><em>extract</em></span>
the <tt class="literal">Vec2</tt> object from held by the Boost.Python <tt class="literal">object</tt>.
</p>
<p>
Take note that we said "attempt to" above. What if the Boost.Python
<code class="literal">object</code> does not really hold a <code class="literal">Vec2</code>
<tt class="literal">object</tt> does not really hold a <tt class="literal">Vec2</tt>
type? This is certainly a possibility considering the dynamic nature of Python
<code class="literal">object</code>s. To be on the safe side, if the C++ type can't
<tt class="literal">object</tt>s. To be on the safe side, if the C++ type can't
be extracted, an appropriate exception is thrown. To avoid an exception,
we need to test for extractibility:
</p>
@@ -260,7 +257,7 @@
<span class="identifier">Vec2</span><span class="special">&amp;</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" alt="tip"></span> The astute reader might have noticed that the <code class="literal">extract&lt;T&gt;</code>
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> The astute reader might have noticed that the <tt class="literal">extract&lt;T&gt;</tt>
facility in fact solves the mutable copying problem:
</p>
<pre class="programlisting">
@@ -273,8 +270,8 @@
<a name="python.enums"></a>Enums</h3></div></div></div>
<p>
Boost.Python has a nifty facility to capture and wrap C++ enums. While Python
has no <code class="literal">enum</code> type, we'll often want to expose our C++ enums
to Python as an <code class="literal">int</code>. Boost.Python's enum facility makes
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:
@@ -293,19 +290,26 @@
</pre>
<p>
can be used to expose to Python. The new enum type is created in the current
<code class="literal">scope()</code>, which is usually the current module. The snippet
above creates a Python class derived from Python's <code class="literal">int</code>
<tt class="literal">scope()</tt>, which is usually the current module. The snippet
above creates a Python class derived from Python's <tt class="literal">int</tt>
type which is associated with the C++ type passed as its first parameter.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td colspan="2" align="left" valign="top">
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><strong>what is a scope?</strong></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>.
</p>
</div>
<span class="bold"><b>what is a scope?</b></span>
</p>
<p>
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>.
</p>
</td></tr>
</table></div>
<p>
You can access those values in Python as
</p>
@@ -342,7 +346,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="functions.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../images/next.png" alt="Next"></a>
<a accesskey="p" href="functions.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -1,25 +1,25 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>General Techniques</title>
<title> General Techniques</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
<link rel="prev" href="exception.html" title="Exception Translation">
<link rel="prev" href="exception.html" title=" Exception Translation">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<table cellpadding="2" width="100%"><tr>
<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>
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
</table>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="exception.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a>
<a accesskey="p" href="exception.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@@ -50,7 +50,7 @@
<p>
We have a C++ library that works with sounds: reading and writing various
formats, applying filters to the sound data, etc. It is named (conveniently)
<code class="literal">sounds</code>. Our library already has a neat C++ namespace hierarchy,
<tt class="literal">sounds</tt>. Our library already has a neat C++ namespace hierarchy,
like so:
</p>
<pre class="programlisting">
@@ -93,18 +93,21 @@
<span class="special">}</span>
</pre>
<p>
Compiling these files will generate the following Python extensions: <code class="literal">core.pyd</code>,
<code class="literal">io.pyd</code> and <code class="literal">filters.pyd</code>.
Compiling these files will generate the following Python extensions: <tt class="literal">core.pyd</tt>,
<tt class="literal">io.pyd</tt> and <tt class="literal">filters.pyd</tt>.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> The extension <code class="literal">.pyd</code> is used for python
extension modules, which are just shared libraries. Using the default for
your system, like <code class="literal">.so</code> for Unix and <code class="literal">.dll</code>
for Windows, works just as well.
</p>
</div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td colspan="2" align="left" valign="top"><p>
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.
</p></td></tr>
</table></div>
<p>
Now, we create this directory structure for our Python package:
</p>
@@ -115,12 +118,12 @@
io.pyd
</pre>
<p>
The file <code class="literal">__init__.py</code> is what tells Python that the directory
<code class="literal">sounds/</code> is actually a Python package. It can be a empty
The file <tt class="literal">__init__.py</tt> is what tells Python that the directory
<tt class="literal">sounds/</tt> is actually a Python package. It can be a empty
file, but can also perform some magic, that will be shown later.
</p>
<p>
Now our package is ready. All the user has to do is put <code class="literal">sounds</code>
Now our package is ready. All the user has to do is put <tt class="literal">sounds</tt>
into his <a href="http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000" target="_top">PYTHONPATH</a>
and fire up the interpreter:
</p>
@@ -159,7 +162,7 @@
</pre>
<p>
Note that we added an underscore to the module name. The filename will have
to be changed to <code class="literal">_core.pyd</code> as well, and we do the same
to be changed to <tt class="literal">_core.pyd</tt> as well, and we do the same
to the other extension modules. Now, we change our package hierarchy like
so:
</p>
@@ -187,11 +190,11 @@
<span class="special">&gt;&gt;&gt;</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>
</pre>
<p>
which is not what we want. But here enters the <code class="literal">__init__.py</code>
magic: everything that is brought to the <code class="literal">__init__.py</code> namespace
which is not what we want. But here enters the <tt class="literal">__init__.py</tt>
magic: everything that is brought to the <tt class="literal">__init__.py</tt> namespace
can be accessed directly by the user. So, all we have to do is bring the
entire namespace from <code class="literal">_core.pyd</code> to <code class="literal">core/__init__.py</code>.
So add this line of code to <code class="literal">sounds<span class="emphasis"><em>core</em></span>__init__.py</code>:
entire namespace from <tt class="literal">_core.pyd</tt> to <tt class="literal">core/__init__.py</tt>.
So add this line of code to <tt class="literal">sounds<span class="emphasis"><em>core</em></span>__init__.py</tt>:
</p>
<pre class="programlisting">
<span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
@@ -208,10 +211,10 @@
with the additional benefit that we can easily add pure Python functions
to any module, in a way that the user can't tell the difference between a
C++ function and a Python function. Let's add a <span class="emphasis"><em>pure</em></span>
Python function, <code class="literal">echo_noise</code>, to the <code class="literal">filters</code>
package. This function applies both the <code class="literal">echo</code> and <code class="literal">noise</code>
filters in sequence in the given <code class="literal">sound</code> object. We create
a file named <code class="literal">sounds/filters/echo_noise.py</code> and code our
Python function, <tt class="literal">echo_noise</tt>, to the <tt class="literal">filters</tt>
package. This function applies both the <tt class="literal">echo</tt> and <tt class="literal">noise</tt>
filters in sequence in the given <tt class="literal">sound</tt> object. We create
a file named <tt class="literal">sounds/filters/echo_noise.py</tt> and code our
function:
</p>
<pre class="programlisting">
@@ -222,14 +225,14 @@
<span class="keyword">return</span> <span class="identifier">s</span>
</pre>
<p>
Next, we add this line to <code class="literal">sounds<span class="emphasis"><em>filters</em></span>__init__.py</code>:
Next, we add this line to <tt class="literal">sounds<span class="emphasis"><em>filters</em></span>__init__.py</tt>:
</p>
<pre class="programlisting">
<span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
</pre>
<p>
And that's it. The user now accesses this function like any other function
from the <code class="literal">filters</code> package:
from the <tt class="literal">filters</tt> package:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
@@ -263,7 +266,7 @@
</p>
<p>
We can do the same with classes that were wrapped with Boost.Python. Suppose
we have a class <code class="literal">point</code> in C++:
we have a class <tt class="literal">point</tt> in C++:
</p>
<p>
</p>
@@ -277,7 +280,7 @@
</pre>
<p>
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 <code class="literal">geom/__init__.py</code>:
Packages</a>, we can code directly into <tt class="literal">geom/__init__.py</tt>:
</p>
<p>
</p>
@@ -292,7 +295,7 @@
</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"><strong>All</strong></span> point instances created from C++ will
<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">
@@ -391,7 +394,7 @@
<span class="special">}</span>
</pre>
<p>
Now you create a file <code class="literal">main.cpp</code>, which contains the <code class="literal">BOOST_PYTHON_MODULE</code>
Now you create a file <tt class="literal">main.cpp</tt>, which contains the <tt class="literal">BOOST_PYTHON_MODULE</tt>
macro, and call the various export functions inside it.
</p>
<pre class="programlisting">
@@ -427,23 +430,28 @@
exporting it to Python at the same time: changes in a class will only demand
the compilation of a single cpp, instead of the entire wrapper code.
</p>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<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 <code class="literal">--multiple</code> option, that generates the
wrappers in various files as demonstrated here.
</p>
</div>
<div class="sidebar">
<p class="title"><b></b></p>
<p>
<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>.
</p>
</div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td colspan="2" align="left" valign="top"><p>
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.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td colspan="2" align="left" valign="top"><p>
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>.
</p></td></tr>
</table></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
@@ -453,7 +461,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="exception.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a>
<a accesskey="p" href="exception.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a>
</div>
</body>
</html>

View File

@@ -49,10 +49,10 @@ Function:
can be exposed to Python by writing a Boost.Python wrapper:
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
@@ -61,7 +61,7 @@ resulting DLL is now visible to Python. Here's a sample Python session:
[python]
>>> import hello
>>> import hello_ext
>>> print hello.greet()
hello, world
@@ -75,43 +75,39 @@ resulting DLL is now visible to Python. Here's a sample Python session:
[h2 From Start To Finish]
Now the first thing you'd want to do is to build the Hello World module and
try it for yourself in Python. In this section, we shall outline the steps
necessary to achieve that. We shall use the build tool that comes bundled
try it for yourself in Python. In this section, we will outline the steps
necessary to achieve that. We will use the build tool that comes bundled
with every boost distribution: [*bjam].
[blurb __note__ [*Building without bjam]\n\n
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 [^bjam].\n\n
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.
[note [*Building without bjam]
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 [^bjam].
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.
]
We shall skip over the details. Our objective will be to simply create the
hello world module and run it in Python. For a complete reference to
building Boost.Python, check out: [@../../../building.html building.html].
After this brief ['bjam] tutorial, we should have built two DLLs:
* boost_python.dll
* hello.pyd
if you are on Windows, and
* libboost_python.so
* hello.so
if you are on Unix.
We will skip over the details. Our objective will be to simply create
the hello world module and run it in Python. For a complete reference to
building Boost.Python, check out: [@../../../building.html
building.html]. After this brief ['bjam] tutorial, we should have built
the DLLs and run a python program using the extension.
The tutorial example can be found in the directory:
[^libs/python/example/tutorial]. There, you can find:
* hello.cpp
* Jamfile
* hello.py
* Jamroot
The [^hello.cpp] file is our C++ hello world example. The [^Jamfile] is a
minimalist ['bjam] script that builds the DLLs for us.
The [^hello.cpp] file is our C++ hello world example. The [^Jamroot] is
a minimalist ['bjam] script that builds the DLLs for us. Finally,
[^hello.py] is our Python program that uses the extension in
[^hello.cpp].
Before anything else, you should have the bjam executable in your boost
directory or somewhere in your path such that [^bjam] can be executed in
@@ -122,51 +118,12 @@ platforms. The complete list of Bjam executables can be found
[h2 Let's Jam!]
__jam__
Here is our minimalist Jamfile:
[@../../../../example/tutorial/Jamroot Here] is our minimalist Jamroot
file. Simply copy the file and tweak [^use-project boost] to where your
boost root directory is and your OK.
[pre
# This is the top of our own project tree
project-root ;
import python ;
extension hello # Declare a Python extension called hello
: hello.cpp # source
# requirements and dependencies for Boost.Python extensions
<template>@boost/libs/python/build/extension
;
]
First, we need to specify our location. You may place your project anywhere.
[^project-root] allows you to do that.
[pre
project-root ;
]
By doing so, you'll need a Jamrules file. Simply copy the one in the
[@../../../../example/tutorial/Jamrules example/tutorial directory] and tweak
the [^path-global BOOST_ROOT] to where your boost root directory is. The file
has [@../../../../example/tutorial/Jamrules detailed instructions] you can follow.
Then we will import the definitions needed by Python modules:
[pre
import python ;
]
Finally we declare our [^hello] extension:
[pre
extension hello # Declare a Python extension called hello
: hello.cpp # source
# requirements and dependencies for Boost.Python extensions
<template>@boost/libs/python/build/extension
;
]
The last part tells BJam that we are depending on the Boost Python Library.
The comments contained in the Jamrules file above should be sufficient
to get you going.
[h2 Running bjam]
@@ -174,98 +131,60 @@ The last part tells BJam that we are depending on the Boost Python Library.
[:Start it up.]
Make sure that the environment is set so that we can invoke the C++
compiler. With MSVC, that would mean running the [^Vcvars32.bat] batch
file. For instance:
A file called user-config.jam in your home directory is used to
configure your tools. In Windows, your home directory can be found by
typing:
[pre
C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat
ECHO %HOMEDRIVE%%HOMEPATH%
]
Some environment variables will have to be setup for proper building of our
Python modules. Example:
into a command prompt window. Your file should at least have the rules
for your compiler and your python installation. A specific example of
this on Windows would be:
[pre
set PYTHON_ROOT=c:/dev/tools/python
set PYTHON_VERSION=2.2
# MSVC configuration
using msvc : 8.0 ;
# Python configuration
using python : 2.4 : C:/dev/tools/Python/ ;
]
The above assumes that the Python installation is in [^c:/dev/tools/python]
and that we are using Python version 2.2. You'll have to tweak these
appropriately.
[blurb __tip__ Be sure not to include a third number, e.g. [*not] "2.2.1",
even if that's the version you have.]
Take note that you may also do that through the Jamrules file we put in
our project as detailed above. The file
has [@../../../../example/tutorial/Jamrules detailed instructions] you
can follow.
The first rule tells Bjam to use the MSVC 8.0 compiler and associated
tools. The second rule provides information on Python, its version and
where it is located. The above assumes that the Python installation is
in [^C:/dev/tools\/Python/]. If you have one fairly "standard" python
installation for your platform, you might not need to do this.
Now we are ready... Be sure to [^cd] to [^libs/python/example/tutorial]
where the tutorial [^"hello.cpp"] and the [^"Jamfile"] is situated.
where the tutorial [^"hello.cpp"] and the [^"Jamroot"] is situated.
Finally:
bjam -sTOOLS=vc-7_1
We are again assuming that we are using Microsoft Visual C++ version 7.1. If
not, then you will have to specify the appropriate tool. See
[@../../../../../../tools/build/index.html Building Boost Libraries] for
further details.
bjam
It should be building now:
[pre
cd C:\dev\boost\libs\python\example\tutorial
bjam -sTOOLS=msvc
bjam
...patience...
...found 1703 targets...
...updating 40 targets...
...found 1101 targets...
...updating 35 targets...
]
And so on... Finally:
[pre
Creating library bin\boost\libs\python\build\boost_python.dll\vc-7_1\debug\th
reading-multi\boost_python.lib and object bin\boost\libs\python\build\boost_pyth
on.dll\vc-7_1\debug\threading-multi\boost_python.exp
vc-C++ bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.obj
hello.cpp
vc-Link bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.pyd bin\tutori
al\hello.pyd\vc-7_1\debug\threading-multi\hello.lib
Creating library bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.li
b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp
...updated 31 targets...
Creating library /path-to-boost_python.dll/
Creating library /path-to-'''hello_ext'''.exp/
'''**passed**''' ... hello.test
...updated 35 targets...
]
If all is well, you should now have:
* boost_python.dll
* hello.pyd
if you are on Windows, and
* libboost_python.so
* hello.so
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 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:
[python]
>>> import hello
>>> print hello.greet()
hello, world
[c++]
Or something similar. If all is well, you should now have built the DLLs and
run the Python program.
[:[*There you go... Have fun!]]
@@ -495,7 +414,7 @@ Doing so, we get some things for free:
Python via a pointer or reference to [^Base] can be passed where a pointer
or reference to [^Derived] is expected.
Now, we shall expose the C++ free functions [^b] and [^d] and [^factory]:
Now, we will expose the C++ free functions [^b] and [^d] and [^factory]:
def("b", b);
def("d", d);
@@ -505,7 +424,7 @@ Note that free function [^factory] is being used to generate new
instances of class [^Derived]. In such cases, we use
[^return_value_policy<manage_new_object>] to instruct Python to adopt
the pointer to [^Base] and hold the instance in a new Python [^Base]
object until the the Python object is destroyed. We shall see more of
object until the the Python object is destroyed. We will see more of
Boost.Python [link python.call_policies call policies] later.
// Tell Python to take ownership of factory's result
@@ -516,7 +435,7 @@ Boost.Python [link python.call_policies call policies] later.
[section Class Virtual Functions]
In this section, we shall learn how to make functions behave polymorphically
In this section, we will learn how to make functions behave polymorphically
through virtual functions. Continuing our example, let us add a virtual function
to our [^Base] class:
@@ -526,13 +445,13 @@ to our [^Base] class:
virtual int f() = 0;
};
One of the goals of Boost.Python is to be minimally intrusive on an existing C++
design. In principle, it should be possible to expose the interface for a 3rd
party library without changing it. It is not ideal to add anything to our class
`Base`. Yet, when you have a virtual function that's going to be overridden in
Python and called polymorphically *from C++*, we'll need to add some
scaffoldings to make things work properly. What we'll do is write a class
wrapper that derives from `Base` that will unintrusively hook into the virtual
One of the goals of Boost.Python is to be minimally intrusive on an existing C++
design. In principle, it should be possible to expose the interface for a 3rd
party library without changing it. It is not ideal to add anything to our class
`Base`. Yet, when you have a virtual function that's going to be overridden in
Python and called polymorphically *from C++*, we'll need to add some
scaffoldings to make things work properly. What we'll do is write a class
wrapper that derives from `Base` that will unintrusively hook into the virtual
functions so that a Python override may be called:
struct BaseWrap : Base, wrapper<Base>
@@ -548,8 +467,10 @@ inherited `wrapper<Base>` (See [@../../../v2/wrapper.html Wrapper]). The
`wrapper` template makes the job of wrapping classes that are meant to
overridden in Python, easier.
[blurb __alert__ [*MSVC6/7 Workaround]\n\n
If you are using Microsoft Visual C++ 6 or 7, you have to write `f` as:\n\n
[blurb __alert__ [*MSVC6/7 Workaround]
If you are using Microsoft Visual C++ 6 or 7, you have to write `f` as:
`return call<int>(this->get_override("f").ptr());`.]
BaseWrap's overridden virtual member function `f` in effect calls the
@@ -561,24 +482,25 @@ Finally, exposing `Base`:
.def("f", pure_virtual(&Base::f))
;
`pure_virtual` signals Boost.Python that the function `f` is a pure virtual
`pure_virtual` signals Boost.Python that the function `f` is a pure virtual
function.
[blurb __note__ [*member function and methods]\n\n Python, like
many object oriented languages uses the term [*methods]. Methods
correspond roughly to C++'s [*member functions]]
[note [*member function and methods]
Python, like many object oriented languages uses the term [*methods].
Methods correspond roughly to C++'s [*member functions]]
[endsect]
[section Virtual Functions with Default Implementations]
We've seen in the previous section how classes with pure virtual functions are
We've seen in the previous section how classes with pure virtual functions are
wrapped using Boost.Python's [@../../../v2/wrapper.html class wrapper]
facilities. If we wish to wrap [*non]-pure-virtual functions instead, the
facilities. If we wish to wrap [*non]-pure-virtual functions instead, the
mechanism is a bit different.
Recall that in the [link python.class_virtual_functions previous section], we
wrapped a class with a pure virtual function that we then implemented in C++, or
Recall that in the [link python.class_virtual_functions previous section], we
wrapped a class with a pure virtual function that we then implemented in C++, or
Python classes derived from it. Our base class:
struct Base
@@ -596,7 +518,7 @@ not declared as pure virtual:
};
We wrap it this way:
struct BaseWrap : Base, wrapper<Base>
{
int f()
@@ -608,24 +530,26 @@ We wrap it this way:
int default_f() { return this->Base::f(); }
};
Notice how we implemented `BaseWrap::f`. Now, we have to check if there is an
Notice how we implemented `BaseWrap::f`. Now, we have to check if there is an
override for `f`. If none, then we call `Base::f()`.
[blurb __alert__ [*MSVC6/7 Workaround]\n\n
[blurb __alert__ [*MSVC6/7 Workaround]
If you are using Microsoft Visual C++ 6 or 7, you have to rewrite the line
with the `*note*` as:\n\n
with the `*note*` as:
`return call<char const*>(f.ptr());`.]
Finally, exposing:
class_<BaseWrap, boost::noncopyable>("Base")
.def("f", &Base::f, &BaseWrap::default_f)
;
Take note that we expose both `&Base::f` and `&BaseWrap::default_f`.
Boost.Python needs to keep track of 1) the dispatch function [^f] and 2) the
forwarding function to its default implementation [^default_f]. There's a
Take note that we expose both `&Base::f` and `&BaseWrap::default_f`.
Boost.Python needs to keep track of 1) the dispatch function [^f] and 2) the
forwarding function to its default implementation [^default_f]. There's a
special [^def] function for this purpose.
In Python, the results would be as expected:
@@ -715,7 +639,7 @@ that correspond to these Python ['special functions]. Example:
Need we say more?
[blurb __note__ What is the business of `operator<<`?
[note What is the business of `operator<<`?
Well, the method `str` requires the `operator<<` to do its work (i.e.
`operator<<` is used by the method defined by `def(str(self))`.]
@@ -725,9 +649,9 @@ Well, the method `str` requires the `operator<<` to do its work (i.e.
[section 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
detail. We will 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
references. We will 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.
@@ -890,18 +814,21 @@ or more policies can be composed by chaining. Here's the general syntax:
Here is the list of predefined call policies. A complete reference detailing
these can be found [@../../../v2/reference.html#models_of_call_policies here].
* [*with_custodian_and_ward]\n Ties lifetimes of the arguments
* [*with_custodian_and_ward_postcall]\n Ties lifetimes of the arguments and results
* [*return_internal_reference]\n Ties lifetime of one argument to that of result
* [*return_value_policy<T> with T one of:]\n
* [*reference_existing_object]\nnaive (dangerous) approach
* [*copy_const_reference]\nBoost.Python v1 approach
* [*copy_non_const_reference]\n
* [*manage_new_object]\n Adopt a pointer and hold the instance
* [*with_custodian_and_ward]: Ties lifetimes of the arguments
* [*with_custodian_and_ward_postcall]: Ties lifetimes of the arguments and results
* [*return_internal_reference]: Ties lifetime of one argument to that of result
* [*return_value_policy<T> with T one of:]
* [*reference_existing_object]: naive (dangerous) approach
* [*copy_const_reference]: Boost.Python v1 approach
* [*copy_non_const_reference]:
* [*manage_new_object]: Adopt a pointer and hold the instance
[blurb :-) [*Remember the Zen, Luke:]\n\n
"Explicit is better than implicit"\n
"In the face of ambiguity, refuse the temptation to guess"\n]
[blurb :-) [*Remember the Zen, Luke:]
"Explicit is better than implicit"
"In the face of ambiguity, refuse the temptation to guess"
]
[endsect]
[section Overloading]
@@ -935,7 +862,7 @@ We have here our C++ class:
};
};
Class X has 4 overloaded functions. We shall start by introducing some
Class X has 4 overloaded functions. We will start by introducing some
member function pointer variables:
bool (X::*fx1)(int) = &X::f;
@@ -1141,7 +1068,7 @@ Then...
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 [^object]. We shall see in
Pythonic variables are just instances of class [^object]. We will see in
this chapter how to deal with Python objects.
As mentioned, one of the goals of Boost.Python is to provide a
@@ -1290,14 +1217,14 @@ we wanted to do above can be achieved by writing:
Vec2& v = extract<Vec2&>(o);
assert(l == v.length());
The first line attempts to extract the "length" attribute of the Boost.Python
[^object]. The second line attempts to ['extract] the [^Vec2] object from held
The first line attempts to extract the "length" attribute of the Boost.Python
[^object]. The second line attempts to ['extract] the [^Vec2] object from held
by the Boost.Python [^object].
Take note that we said "attempt to" above. What if the Boost.Python [^object]
does not really hold a [^Vec2] type? This is certainly a possibility considering
the dynamic nature of Python [^object]s. To be on the safe side, if the C++ type
can't be extracted, an appropriate exception is thrown. To avoid an exception,
Take note that we said "attempt to" above. What if the Boost.Python [^object]
does not really hold a [^Vec2] type? This is certainly a possibility considering
the dynamic nature of Python [^object]s. To be on the safe side, if the C++ type
can't be extracted, an appropriate exception is thrown. To avoid an exception,
we need to test for extractibility:
extract<Vec2&> x(o);
@@ -1335,10 +1262,12 @@ current [^scope()], which is usually the current module. The snippet above
creates a Python class derived from Python's [^int] type which is
associated with the C++ type passed as its first parameter.
[blurb __note__ [*what is a scope?]\n\n 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 [@../../../v2/scope.html here].]
[note [*what is a scope?]
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
[@../../../v2/scope.html here].]
You can access those values in Python as
@@ -1433,15 +1362,15 @@ Being able to build is nice, but there is nothing to build yet. Embedding
the Python interpreter into one of your C++ programs requires these 4
steps:
# '''#include''' [^<boost/python.hpp>]\n\n
# '''#include''' [^<boost/python.hpp>]
# Call Py_Initialize() to start the interpreter and create the [^__main__] module.\n\n
# Call Py_Initialize() to start the interpreter and create the [^__main__] module.
# Call other Python C API routines to use the interpreter.\n\n
# Call other Python C API routines to use the interpreter.
[/ # Call Py_Finalize() to stop the interpreter and release its resources.]
[blurb __note__ [*Note that at this time you must not call Py_Finalize() to stop the
[note [*Note that at this time you must not call Py_Finalize() to stop the
interpreter. This may be fixed in a future version of boost.python.]
]
@@ -1499,10 +1428,10 @@ containing a phrase that is well-known in programming circles.
[h2 Manipulating Python objects]
Often we'd like to have a class to manipulate Python objects.
But we have already seen such a class above, and in the
[@python/object.html previous section]: the aptly named [^object] class
and its derivatives. We've already seen that they can be constructed from
Often we'd like to have a class to manipulate Python objects.
But we have already seen such a class above, and in the
[@python/object.html previous section]: the aptly named [^object] class
and its derivatives. We've already seen that they can be constructed from
a [^handle]. The following examples should further illustrate this fact:
object main_module = import("__main__");
@@ -1650,7 +1579,7 @@ 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 an STL algorithm or use it to initialize an STL
container. We need to make a Python iterator look like an STL iterator.
For that, we use `stl_input_iterator<>`. Consider how we might
For that, we use `stl_input_iterator<>`. Consider how we might
implement a function that exposes `std::list<int>::assign()` to
Python:
@@ -1754,7 +1683,7 @@ separately with Boost.Python, like this:
Compiling these files will generate the following Python extensions:
[^core.pyd], [^io.pyd] and [^filters.pyd].
[blurb __note__ The extension [^.pyd] is used for python extension modules, which
[note The extension [^.pyd] is used for python extension modules, which
are just shared libraries. Using the default for your system, like [^.so] for
Unix and [^.dll] for Windows, works just as well.]
@@ -2025,11 +1954,11 @@ This method is recommended too if you are developing the C++ library and
exporting it to Python at the same time: changes in a class will only demand
the compilation of a single cpp, instead of the entire wrapper code.
[blurb __note__ If you're exporting your classes with [@../../../../pyste/index.html Pyste],
[note If you're exporting your classes with [@../../../../pyste/index.html Pyste],
take a look at the [^--multiple] option, that generates the wrappers in
various files as demonstrated here.]
[blurb __note__ This method is useful too if you are getting the error message
[note This method is useful too if you are getting the error message
['"fatal error C1204:Compiler limit:internal structure overflow"] when compiling
a large source file, as explained in the [@../../../v2/faq.html#c1204 FAQ].]

View File

@@ -4,7 +4,7 @@
# Specify the path to the Boost project. If you move this project,
# adjust this path to refer to the Boost root directory.
use-project boost
use-project boost
: ../../../.. ;
# Set up the project-wide requirements that everything uses the
@@ -13,6 +13,19 @@ use-project boost
project
: requirements <library>/boost/python//boost_python ;
# Declare a Python extension called hello.
python-extension hello : hello.cpp ;
# Declare the three extension modules. You can specify multiple
# source files after the colon separated by spaces.
python-extension hello_ext : hello.cpp ;
# A little "rule" (function) to clean up the syntax of declaring tests
# of these extension modules.
local rule run-test ( test-name : sources + )
{
import testing ;
testing.make-test run-pyd : $(sources) : : $(test-name) ;
}
# Declare test targets
run-test hello : hello_ext hello.py ;

View File

@@ -1,20 +1,20 @@
// Copyright Joel de Guzman 2002-2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
// Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
// Hello World Example from the tutorial
// [Joel de Guzman 10/9/2002]
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
char const* greet()
{
return "hello, world";
}
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}

7
example/tutorial/hello.py Executable file
View File

@@ -0,0 +1,7 @@
# Copyright Joel de Guzman 2002-2007. Distributed under the Boost
# Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
# or copy at http://www.boost.org/LICENSE_1_0.txt)
# Hello World Example from the tutorial
import hello_ext
print hello_ext.greet()