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

Compare commits

..

24 Commits

Author SHA1 Message Date
nobody
43fb8c5a0f This commit was manufactured by cvs2svn to create tag
'Version_1_32_0'.

[SVN r26264]
2004-11-19 19:19:18 +00:00
Aleksey Gurtovoy
1a221e80b2 fix invalid (quickbook generated) links
[SVN r26263]
2004-11-19 19:19:17 +00:00
Aleksey Gurtovoy
41deb6855c correct //wrapper link
[SVN r26261]
2004-11-19 16:12:36 +00:00
Dave Abrahams
72207ba070 merged from trunk
[SVN r26259]
2004-11-19 15:51:02 +00:00
Dave Abrahams
f20ff9f9d6 merged from trunk
[SVN r26256]
2004-11-19 14:17:59 +00:00
Aleksey Gurtovoy
1afc3580a3 new MPL docs
[SVN r26213]
2004-11-15 12:30:30 +00:00
Joel de Guzman
ee1328e10d New Wrapper Facility
[SVN r26209]
2004-11-15 06:55:48 +00:00
Joel de Guzman
9ccde24cff New Wrapper Facility
[SVN r26208]
2004-11-15 06:43:54 +00:00
Joel de Guzman
168c8c692a New Wrapper Facility
[SVN r26207]
2004-11-15 06:34:34 +00:00
Dave Abrahams
3540d4fcf4 merged from trunk
[SVN r26090]
2004-11-02 20:11:53 +00:00
Dave Abrahams
0ccded7df3 merged from trunk
[SVN r26068]
2004-11-01 21:24:48 +00:00
nobody
f81c779823 This commit was manufactured by cvs2svn to create branch 'RC_1_32_0'.
[SVN r26058]
2004-11-01 16:41:45 +00:00
Dave Abrahams
8e4c69ee5a merged from trunk
[SVN r26050]
2004-11-01 14:17:40 +00:00
Dave Abrahams
3af8dc41d7 merged from trunk
[SVN r26048]
2004-11-01 14:15:48 +00:00
Dave Abrahams
1286cb0527 merged from trunk
[SVN r26027]
2004-11-01 00:23:09 +00:00
Aleksey Gurtovoy
baf3c962f3 fix broken links
[SVN r25987]
2004-10-31 02:50:40 +00:00
Joel de Guzman
6c7c9fb61f Fixed broken links
[SVN r25986]
2004-10-31 01:48:48 +00:00
Aleksey Gurtovoy
8aeaed2e5f fix libraries.html and other broken links
[SVN r25983]
2004-10-30 14:30:51 +00:00
Joel de Guzman
44b1c14d7e Fixed links
[SVN r25977]
2004-10-30 10:39:28 +00:00
Aleksey Gurtovoy
d65734aac4 merged const_argument fixes from the main trunk
[SVN r25925]
2004-10-29 03:21:18 +00:00
John Maddock
c99bd3ab00 Merged added copyrights from main branch.
[SVN r25913]
2004-10-28 11:06:12 +00:00
John Maddock
259a258123 BSL updates based on permissions in blanket-permission.txt
[SVN r25862]
2004-10-25 11:51:16 +00:00
Aleksey Gurtovoy
858055cd0a merge fixes from the main trunk
[SVN r25849]
2004-10-24 07:32:42 +00:00
nobody
197bb21fb7 This commit was manufactured by cvs2svn to create branch 'RC_1_32_0'.
[SVN r25797]
2004-10-20 08:26:43 +00:00
315 changed files with 8980 additions and 9856 deletions

95
build/Jamfile Normal file
View File

@@ -0,0 +1,95 @@
# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears
# in all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
#
# Boost.Python library Jamfile
# declare the location of this subproject relative to the root
subproject libs/python/build ;
# bring in the rules for python
import python ;
if [ check-python-config ]
{
local bpl-linkflags ;
if $(UNIX) && ( $(OS) = AIX )
{
bpl-linkflags = <linkflags>"-e initlibboost_python" ;
}
# Enabling intrinsics (/0i) or maximize speed (/02) seem to cause
# internal compiler errors with this toolset.
local msvc-stlport-workarounds
= <optimization>off "<cxxflags>-Ogty -O1 -Gs" ;
local sources =
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
aix_init_module.cpp
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object_protocol.cpp
object_operators.cpp
wrapper.cpp
;
dll boost_python
: ../src/$(sources)
: $(BOOST_PYTHON_V2_PROPERTIES)
<define>BOOST_PYTHON_SOURCE
$(bpl-linkflags)
<msvc-stlport><release>$(msvc-stlport-workarounds)
<darwin><*><linkflags>-bind_at_load
;
template extension
: <dll>boost_python
: <sysinclude>../../..
;
lib boost_python
: # sources
../src/$(sources)
: # requirements
$(BOOST_PYTHON_V2_PROPERTIES)
<define>BOOST_PYTHON_SOURCE
<define>BOOST_STATIC_LIB
$(bpl-linkflags)
<msvc-stlport><release>$(msvc-stlport-workarounds)
;
stage bin-stage : <dll>boost_python <lib>boost_python
: <tag><debug>"_debug"
<tag><debug-python>"_pydebug"
:
debug release
;
install python lib
: <dll>boost_python <lib>boost_python
;
}

View File

@@ -1,42 +1,67 @@
# Copyright David Abrahams 2001-2006. 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)
import os ;
import modules ;
import python ;
# Use a very crude way to sense there python is locatted
if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
local PYTHON_PATH = [ modules.peek : PYTHON_PATH ] ;
if [ GLOB /usr/local/include/python2.2 : * ]
{
# Attempt default configuration of python
import toolset : using ;
using python ;
if ! [ python.configured ]
{
ECHO "WARNING: No python installation configured and autoconfiguration" ;
ECHO " failed. See http://www.boost.org/libs/python/doc/building.html" ;
ECHO " for configuration instructions or pass --without-python to" ;
ECHO " suppress this message and silently skip all Boost.Python targets" ;
}
PYTHON_PATH = /usr/local ;
}
else if [ GLOB /usr/include/python2.2 : * ]
{
PYTHON_PATH = /usr ;
}
if [ python.configured ] {
if [ os.name ] in CYGWIN NT
{
lib_condition = <link>shared: ;
defines = USE_DL_IMPORT ;
# Declare a target for the python interpreter library
lib python : : <name>python22 <search>$(PYTHON_PATH)/libs ;
PYTHON_LIB = python ;
}
else
{
lib python : : <name>python2.2 ;
PYTHON_LIB = python ;
}
if $(PYTHON_PATH) {
project boost/python
: source-location ../src
: requirements <include>$(PYTHON_PATH)/include
$(lib_condition)<library-path>$(PYTHON_PATH)/libs
<link>shared:<library>$(PYTHON_LIB)
<define>$(defines)
: usage-requirements # requirement that will be propageted to *users* of this library
<include>$(PYTHON_PATH)/include
# We have a bug which causes us to conclude that conditionalized
# properties in this section are not free.
# $(lib_condition)<library-path>$(PYTHON_PATH)/lib/python2.2/config
# <shared>true:<find-library>$(PYTHON_LIB)
<library-path>$(PYTHON_PATH)/lib/python2.2/config
<library>$(PYTHON_LIB)
;
lib boost_python
: # sources
:
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
aix_init_module.cpp
converter/from_python.cpp
@@ -53,41 +78,10 @@ lib boost_python
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object/stl_iterator.cpp
object_protocol.cpp
object_operators.cpp
wrapper.cpp
import.cpp
exec.cpp
: # requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
: <link>static:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
# On Windows, all code using Python has to link to the Python
# import library.
#
# On *nix we never link libboost_python to libpython. When
# extending Python, all Python symbols are provided by the
# Python interpreter executable. When embedding Python, the
# client executable is expected to explicitly link to
# /python//python (the target representing libpython) itself.
#
# python_for_extensions is a target defined by Boost.Build to
# provide the Python include paths, and on Windows, the Python
# import library, as usage requirements.
<library>/python//python_for_extensions
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
}
else
{
ECHO "warning: Python location is not configured" ;
ECHO "warning: the Boost.Python library won't be built" ;
: <link>shared
;
}

View File

@@ -175,14 +175,6 @@ SOURCE=..\..\src\converter\registry.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\slice.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\object\stl_iterator.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\str.cpp
# End Source File
# Begin Source File
@@ -193,18 +185,6 @@ SOURCE=..\..\src\tuple.cpp
SOURCE=..\..\src\converter\type_id.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\wrapper.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\import.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\exec.cpp
# End Source File
# End Group
# Begin Group "Header Files"
@@ -606,10 +586,6 @@ SOURCE=..\..\..\..\boost\python\object\select_holder.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\stl_iterator_core.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\value_holder.hpp
# End Source File
# Begin Source File
@@ -867,10 +843,6 @@ SOURCE=..\..\..\..\boost\python\slice_nil.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\stl_iterator.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\str.hpp
# End Source File
# Begin Source File

BIN
build/python_v1.zip Normal file

Binary file not shown.

View File

@@ -1,11 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,5 +1 @@
.. Copyright David Abrahams 2006. 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)
This file has been moved to http://www.boost-consulting.com/writing/bpl.txt.

View File

@@ -1,7 +1,3 @@
Copyright David Abrahams 2006. 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)
.. This is a comment. Note how any initial comments are moved by
transforms to after the document title, subtitle, and docinfo.
@@ -277,7 +273,7 @@ correctly:
==================
This section outlines some of the library's major features. Except as
necessary to avoid confusion, details of library implementation are
neccessary to avoid confusion, details of library implementation are
omitted.
-------------------------------------------
@@ -541,7 +537,7 @@ This has two effects:
called with an object wrapping a ``Derived`` instance. Wrapped
member functions of class ``T`` are treated as though they have an
implicit first argument of ``T&``, so these conversions are
necessary to allow the base class methods to be called for derived
neccessary to allow the base class methods to be called for derived
objects.
Of course it's possible to derive new Python classes from wrapped C++
@@ -654,7 +650,7 @@ Things to notice about the dispatcher class:
called on an object of type ``BaseWrap``, since it overrides ``f``.
Admittedly, this formula is tedious to repeat, especially on a project
with many polymorphic classes; that it is necessary reflects
with many polymorphic classes; that it is neccessary reflects
limitations in C++'s compile-time reflection capabilities. Several
efforts are underway to write front-ends for Boost.Python which can
generate these dispatchers (and other wrapping code) automatically.

View File

@@ -5,8 +5,6 @@
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
boostinspect:nolicense
Default cascading style sheet for the HTML output of Docutils.
*/

View File

@@ -1,7 +1,3 @@
/* Copyright David Abrahams 2006. 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)
*/
H1
{
FONT-SIZE: 200%

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -66,9 +63,11 @@
<hr>
<h2><a name="requirements">Requirements</a></h2>
<b>Boost.Python</b> requires <a href=
<b>Boost.Python</b> version 2 requires <a href=
"http://www.python.org/2.2">Python 2.2</a> <i>or <a href=
"http://www.python.org">newer</a></i>.
"http://www.python.org">newer</a></i>. An unsupported archive of
Boost.Python version 1, which works with versions of Python since 1.5.2,
is available <a href="../build/python_v1.zip">here</a>.
<h2><a name="building">Building Boost.Python</a></h2>
@@ -83,12 +82,9 @@
boost installation (if you have already built boost from the top level
this may have no effect, since the work is already done).</p>
<h3><a name="configuration">Basic Configuration</a></h3> You may
need to configure the following variables to point Boost.Build at
your Python installation. Variables can be either set in the
environment or passed on the <code>bjam</code> command-line
as <code>-s</code><i>name</i><code>=</code><i>value</i>. Variable
names are case-sensitive.
<h3><a name="configuration">Basic Configuration</a></h3>
You may need to configure the following variables to point Boost.Build at
your Python installation:
<table border="1" summary="build configuration variables">
<tr>
@@ -102,29 +98,28 @@
</tr>
<tr>
<td><code>PYTHON_ROOT</code></td>
<td>The root directory of your Python installation</td>
<td>Windows:&nbsp;<code>c:/tools/python</code>
Unix:&nbsp;<code>/usr/local</code></td>
<td>On Unix, this is the <code>--with-prefix=</code> directory used
to configure Python</td>
</tr>
<tr>
<td><code>PYTHON_VERSION</code></td>
<td>The The 2-part python Major.Minor version number</td>
<td><code>2.4</code></td>
<td><code>2.2</code></td>
<td>Be sure not to include a third number, e.g. <b>not</b>
"<code>2.2.1</code>", even if that's the version you have.</td>
</tr>
<td><code>PYTHON_ROOT</code></td>
<td>The root directory of your Python installation</td>
<td>Windows:&nbsp;<code>c:/Python</code><i>(10*Version)</i>, e.g. <code>c:/Python24</code>
<br>
*nix/Cygwin:&nbsp;<code>/usr</code></td>
<td>On *nix, this should be the <code>--prefix=</code> directory used
to configure Python when it was built and installed.</td>
</tr>
<tr>
<td><code>PYTHON_INCLUDES</code></td>
@@ -177,7 +172,7 @@
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]ROOT</code></td>
<td>*nix-style path containing the <code>include/</code> directory
<td>unix-style path containing the <code>include/</code> directory
containing
<code>python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h</code>.</td>
@@ -224,10 +219,8 @@
<h3><a name="mingw">Notes for MinGW (and Cygwin with -mno-cygwin) GCC
Users</a></h3>
<p>If you are using a version of Python prior to 2.4.1 with a
MinGW prior to 3.0.0 (with binutils-2.13.90-20030111-1), you will
need to create a MinGW-compatible version of the Python library;
the one shipped with Python will only work with a
<p>You will need to create a MinGW-compatible version of the Python
library; the one shipped with Python will only work with a
Microsoft-compatible linker. Follow the instructions in the
"Non-Microsoft" section of the "Building Extensions: Tips And Tricks"
chapter in <a href=
@@ -309,7 +302,7 @@ bjam -sTOOLS=<i><a href=
right places.
</blockquote>
<p>The <code>libs/python/example</code>
<p>The <code><a href="../example">libs/python/example</a></code>
subdirectory of your boost installation contains a small example which
builds and tests two extensions. To build your own extensions copy the
example subproject and make the following two edits:</p>
@@ -366,7 +359,7 @@ path-global BOOST_ROOT : ../../.. ;
<p>The first two variants of the <code>boost_python</code> library are
built by default, and are compatible with the default Python
distribution. The <code>debug-python</code> variant corresponds to a
specially-built debugging version of Python. On *nix platforms, this
specially-built debugging version of Python. On Unix platforms, this
python is built by adding <code>--with-pydebug</code> when configuring
the Python build. On Windows, the debugging version of Python is
generated by the "Win32 Debug" target of the <code>PCBuild.dsw</code>
@@ -403,8 +396,8 @@ path-global BOOST_ROOT : ../../.. ;
IDE</a></h2>
<p>For the those of you who feel more comfortable in the IDE world, a
workspace and project file have been included in the <code>
libs/python/build/VisualStudio</code> subdirectory.
workspace and project file have been included in the <a href=
"../build/VisualStudio">libs/python/build/VisualStudio</a> subdirectory.
It builds release and debug versions of the Boost.Python libraries and
places them and the same directory as Jamfile build does, though the
intermediate object files are placed in a different directory. The files
@@ -444,7 +437,7 @@ path-global BOOST_ROOT : ../../.. ;
<blockquote>
<em>The Visual Studio project files are graciously contributed and
maintained by <a href="mailto:brett.calcott@gmail.com">Brett
maintained by <a href="mailto:brett.calcott@paradise.net.nz">Brett
Calcott</a></em>.
</blockquote>
<hr>

View File

@@ -1,14 +1,11 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python</title>
</head>
@@ -27,60 +24,10 @@
<h2 align="center">Index</h2>
</td>
<td align="right">
<form method="get" action="http://www.google.com/custom">
<p>
<span id= "search-choice">
Search
<select name="hq" id="hq">
<option label="All Documentation" value=
"site:www.boost.org inurl:www.boost.org/libs/python/doc">
All Documentation
</option>
<option label="Tutorial" value=
"site:www.boost.org inurl:www.boost.org/libs/python/doc/tutorial">
Tutorial
</option>
<option label="Reference" value=
"site:www.boost.org inurl:www.boost.org/libs/python/doc/v2">
Reference
</option>
</select>
<br>
</span>
<span id="search-text">
<input type="text" name="q" id="q" size="31" maxlength="255" alt="Search Text" />
</span>
<br>
<span id= "google">
<a href= "http://www.google.com/search">
<img src="../../../more/google_logo_25wht.gif" alt="Google" border="0" /></a>Powered
</span>
<span id="go">
<input type="image" name="search" src="../../../more/space.gif" alt="Search" id="search-button" />
</span>
<br>
<input type="hidden" name="cof" value= "LW:277;L:http://www.boost.org/boost.png;LH:86;AH:center;GL:0;S:http://www.boost.org;AWFID:9b83d16ce652ed5a;" />
<input type="hidden" name="sa" value= "Google Search" />
<input type="hidden" name= "domains" value= "www.boost.org;mail.python.org" /></p>
</form>
</td>
</tr>
<tr>
</tr>
</table>
<hr>
<h2>Synopsis</h2>
Welcome to version 2 of <b>Boost.Python</b>, a C++ library which enables
seamless interoperability between C++ and the <a href=

328
doc/new-conversions.html Normal file
View File

@@ -0,0 +1,328 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>A New Type Conversion Mechanism for Boost.Python</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p><img border="0" src="../../../boost.png" width="277" height="86"
alt="boost logo"></p>
<h1>A New Type Conversion Mechanism for Boost.Python</h1>
<p>By <a href="../../../people/dave_abrahams.htm">David Abrahams</a>.
<h2>Introduction</h2>
This document describes a redesign of the mechanism for automatically
converting objects between C++ and Python. The current implementation
uses two functions for any type <tt>T</tt>:
<blockquote><pre>
U from_python(PyObject*, type&lt;T&gt;);
void to_python(V);
</pre></blockquote>
where U is convertible to T and T is convertible to V. These functions
are at the heart of C++/Python interoperability in Boost.Python, so
why would we want to change them? There are many reasons:
<h3>Bugs</h3>
<p>Firstly, the current mechanism relies on a common C++ compiler
bug. This is not just embarrassing: as compilers get to be more
conformant, the library stops working. The issue, in detail, is the
use of inline friend functions in templates to generate
conversions. It is a very powerful, and legal technique as long as
it's used correctly:
<blockquote><pre>
template &lt;class Derived&gt;
struct add_some_functions
{
friend <i>return-type</i> some_function1(..., Derived <i>cv-*-&amp;-opt</i>, ...);
friend <i>return-type</i> some_function2(..., Derived <i>cv-*-&amp;-opt</i>, ...);
};
template &lt;class T&gt;
struct some_template : add_some_functions&lt;some_template&lt;T&gt; &gt;
{
};
</pre></blockquote>
The <tt>add_some_functions</tt> template generates free functions
which operate on <tt>Derived</tt>, or on related types. Strictly
speaking the related types are not just cv-qualified <tt>Derived</tt>
values, pointers and/or references. Section 3.4.2 in the standard
describes exactly which types you must use as parameters to these
functions if you want the functions to be found
(there is also a less-technical description in section 11.5.1 of
C++PL3 <a href="#ref_1">[1]</a>). Suffice it to say that
with the current design, the <tt>from_python</tt> and
<tt>to_python</tt> functions are not supposed to be callable under any
conditions!
<h3>Compilation and Linking Time</h3>
The conversion functions generated for each wrapped class using the
above technique are not function templates, but regular functions. The
upshot is that they must <i>all</i> be generated regardless of whether
they are actually used. Generating all of those functions can slow
down module compilation, and resolving the references can slow down
linking.
<h3>Efficiency</h3>
The conversion functions are primarily used in (member) function
wrappers to convert the arguments and return values. Being functions,
converters have no interface which allows us to ask &quot;will the
conversion succeed?&quot; without calling the function. Since the
return value of the function must be the object to be passed as an
argument, Boost.Python currently uses C++ exception-handling to detect
an unsuccessful conversion. It's not a particularly good use of
exception-handling, since the failure is not handled very far from
where it occurred. More importantly, it means that C++ exceptions are
thrown during overload resolution as we seek an overload that matches
the arguments passed. Depending on the implementation, this approach
can result in significant slowdowns.
<p>It is also unclear that the current library generates a minimal
amount of code for any type conversion. Many of the conversion
functions are nontrivial, and partly because of compiler limitations,
they are declared <tt>inline</tt>. Also, we could have done a better
job separating the type-specific conversion code from the code which
is type-independent.
<h3>Cross-module Support</h3>
The current strategy requires every module to contain the definition
of conversions it uses. In general, a new module can never supply
conversion code which is used by another module. Ralf Grosse-Kunstleve
designed a clever system which imports conversions directly from one
library into another using some explicit declarations, but it has some
disadvantages also:
<ol>
<li>The system Ullrich Koethe designed for implicit conversion between
wrapped classes related through inheritance does not currently work if
the classes are defined in separate modules.
<li>The writer of the importing module is required to know the name of
the module supplying the imported conversions.
<li>There can be only one way to extract any given C++ type from a
Python object in a given module.
</ol>
The first item might be addressed by moving Boost.Python into a shared
library, but the other two cannot. Ralf turned the limitation in item
two into a feature: the required module is loaded implicitly when a
conversion it defines is invoked. We will probably want to provide
that functionality anyway, but it's not clear that we should require
the declaration of all such conversions. The final item is a more
serious limitation. If, for example, new numeric types are defined in
separate modules, and these types can all be converted to
<tt>double</tt>s, we have to choose just one conversion method.
<h3>Ease-of-use</h3>
One persistent source of confusion for users of Boost.Python has been
the fact that conversions for a class are not be visible at
compile-time until the declaration of that class has been seen. When
the user tries to expose a (member) function operating on or returning
an instance of the class in question, compilation fails...even though
the user goes on to expose the class in the same translation unit!
<p>
The new system lifts all compile-time checks for the existence of
particular type conversions and replaces them with runtime checks, in
true Pythonic style. While this might seem cavalier, the compile-time
checks are actually not much use in the current system if many classes
are wrapped in separate modules, since the checks are based only on
the user's declaration that the conversions exist.
<h2>The New Design</h2>
<h3>Motivation</h3>
The new design was heavily influenced by a desire to generate as
little code as possible in extension modules. Some of Boost.Python's
clients are enormous projects where link time is proportional to the
amount of object code, and there are many Python extension modules. As
such, we try to keep type-specific conversion code out of modules
other than the one the converters are defined in, and rely as much as
possible on centralized control through a shared library.
<h3>The Basics</h3>
The library contains a <tt>registry</tt> which maps runtime type
identifiers (actually an extension of <tt>std::type_info</tt> which
preserves references and constness) to entries containing type
converters. An <tt>entry</tt> can contain only one converter from C++ to Python
(<tt>wrapper</tt>), but many converters from Python to C++
(<tt>unwrapper</tt>s). <font color="#ff0000">What should happen if
multiple modules try to register wrappers for the same type?</font>. Wrappers
and unwrappers are known as <tt>body</tt> objects, and are accessed
by the user and the library (in its function-wrapping code) through
corresponding <tt>handle</tt> (<tt>wrap&lt;T&gt;</tt> and
<tt>unwrap&lt;T&gt;</tt>) objects. The <tt>handle</tt> objects are
extremely lightweight, and delegate <i>all</i> of their operations to
the corresponding <tt>body</tt>.
<p>
When a <tt>handle</tt> object is constructed, it accesses the
registry to find a corresponding <tt>body</tt> that can convert the
handle's constructor argument. Actually the registry record for any
type
<tt>T</tt>used in a module is looked up only once and stored in a
static <tt>registration&lt;T&gt;</tt> object for efficiency. For
example, if the handle is an <tt>unwrap&lt;Foo&amp;&gt;</tt> object,
the <tt>entry</tt> for <tt>Foo&amp;</tt> is looked up in the
<tt>registry</tt>, and each <tt>unwrapper</tt> it contains is queried
to determine if it can convert the
<tt>PyObject*</tt> with which the <tt>unwrap</tt> was constructed. If
a body object which can perform the conversion is found, a pointer to
it is stored in the handle. A body object may at any point store
additional data in the handle to speed up the conversion process.
<p>
Now that the handle has been constructed, the user can ask it whether
the conversion can be performed. All handles can be tested as though
they were convertible to <tt>bool</tt>; a <tt>true</tt> value
indicates success. If the user forges ahead and tries to do the
conversion without checking when no conversion is possible, an
exception will be thrown as usual. The conversion itself is performed
by the body object.
<h3>Handling complex conversions</h3>
<p>Some conversions may require a dynamic allocation. For example,
when a Python tuple is converted to a <tt>std::vector&lt;double&gt;
const&amp;</tt>, we need some storage into which to construct the
vector so that a reference to it can be formed. Furthermore, multiple
conversions of the same type may need to be &quot;active&quot;
simultaneously, so we can't keep a single copy of the storage
anywhere. We could keep the storage in the <tt>body</tt> object, and
have the body clone itself in case the storage is used, but in that
case the storage in the body which lives in the registry is never
used. If the storage was actually an object of the target type (the
safest way in C++), we'd have to find a way to construct one for the
body in the registry, since it may not have a default constructor.
<p>
The most obvious way out of this quagmire is to allocate the object using a
<i>new-expression</i>, and store a pointer to it in the handle. Since
the <tt>body</tt> object knows everything about the data it needs to
allocate (if any), it is also given responsibility for destroying that
data. When the <tt>handle</tt> is destroyed it asks the <tt>body</tt>
object to tear down any data it may have stored there. In many ways,
you can think of the <tt>body</tt> as a &quot;dynamically-determined
vtable&quot; for the handle.
<h3>Eliminating Redundancy</h3>
If you look at the current Boost.Python code, you'll see that there
are an enormous number of conversion functions generated for each
wrapped class. For a given class <tt>T</tt>, functions are generated
to extract the following types <tt>from_python</tt>:
<blockquote><pre>
T*
T const*
T const* const&amp;
T* const&amp;
T&amp;
T const&amp;
T
std::auto_ptr&lt;T&gt;&amp;
std::auto_ptr&lt;T&gt;
std::auto_ptr&lt;T&gt; const&amp;
boost::shared_ptr&lt;T&gt;&amp;
boost::shared_ptr&lt;T&gt;
boost::shared_ptr&lt;T&gt; const&amp;
</pre></blockquote>
Most of these are implemented in terms of just a few conversions, and
<t>if you're lucky</t>, they will be inlined and cause no extra
overhead. In the new system, however, a significant amount of data
will be associated with each type that needs to be converted. We
certainly don't want to register a separate unwrapper object for all
of the above types.
<p>Fortunately, much of the redundancy can be eliminated. For example,
if we generate an unwrapper for <tt>T&</tt>, we don't need an
unwrapper for <tt>T const&</tt> or <tt>T</tt>. Accordingly, the user's
request to wrap/unwrap a given type is translated at compile-time into
a request which helps to eliminate redundancy. The rules used to
<tt>unwrap</tt> a type are:
<ol>
<li> Treat built-in types specially: when unwrapping a value or
constant reference to one of these, use a value for the target
type. It will bind to a const reference if neccessary, and more
importantly, avoids having to dynamically allocate room for
an lvalue of types which can be cheaply copied.
<li>
Reduce everything else to a reference to an un-cv-qualified type
where possible. Since cv-qualification is lost on Python
anyway, there's no point in trying to convert to a
<tt>const&amp;</tt>. <font color="#ff0000">What about conversions
to values like the tuple-&gt;vector example above? It seems to me
that we don't want to make a <tt>vector&lt;double&gt;&amp;</tt>
(non-const) converter available for that case. We may need to
rethink this slightly.</font>
</ol>
<p>To handle the problem described above in item 2, we modify the
procedure slightly. To unwrap any non-scalar <tt>T</tt>, we seek an
unwrapper for <tt>add_reference&lt;T&gt;::type</tt>. Unwrappers for
<tt>T&nbsp;const&amp;</tt> always return <tt>T&amp;</tt>, and are
registered under both <tt>T&nbsp;&amp;</tt> and
<tt>T&nbsp;const&amp;</tt>.
<p>For compilers not supporting partial specialization, unwrappers for
<tt>T&nbsp;const&amp;</tt> must return <tt>T&nbsp;const&amp;</tt>
(since constness can't be stripped), but a separate unwrapper object
need to be registered for <tt>T&nbsp;&amp;</tt> and
<tt>T&nbsp;const&amp;</tt> anyway, for the same reasons.
<font color="#ff0000">We may want to make it possible to compile as
though partial specialization were unavailable even on compilers where
it is available, in case modules could be compiled by different
compilers with compatible ABIs (e.g. Intel C++ and MSVC6).</font>
<h3>Efficient Argument Conversion</h3>
Since type conversions are primarily used in function wrappers, an
optimization is provided for the case where a group of conversions are
used together. Each <tt>handle</tt> class has a corresponding
&quot;<tt>_more</tt>&quot; class which does the same job, but has a
trivial destructor. Instead of asking each &quot;<tt>_more</tt>&quot;
handle to destroy its own body, it is linked into an endogenous list
managed by the first (ordinary) handle. The <tt>wrap</tt> and
<tt>unwrap</tt> destructors are responsible for traversing that list
and asking each <tt>body</tt> class to tear down its
<tt>handle</tt>. This mechanism is also used to determine if all of
the argument/return-value conversions can succeed with a single
function call in the function wrapping code. <font color="#ff0000">We
might need to handle return values in a separate step for Python
callbacks, since the availablility of a conversion won't be known
until the result object is retrieved.</font>
<br>
<hr>
<h2>References</h2>
<p><a name="ref_1">[1]</a>B. Stroustrup, The C++ Programming Language
Special Edition Addison-Wesley, ISBN 0-201-70073-5.
<hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="31283" --></p>
<p>© Copyright David Abrahams, 2001</p>
</body>
</html>

111
doc/new-conversions.txt Normal file
View File

@@ -0,0 +1,111 @@
This hierarchy contains converter handle classes.
+-------------+
| noncopyable |
+-------------+
^
| A common base class used so that
+--------+--------+ conversions can be linked into a
| conversion_base | chain for efficient argument
+-----------------+ conversion
^
|
+---------+-----------+
| |
+-----------+----+ +------+-------+ only used for
| unwrap_more<T> | | wrap_more<T> | chaining, and don't manage any
+----------------+ +--------------+ resources.
^ ^
| |
+-----+-----+ +-------+-+ These converters are what users
| unwrap<T> | | wrap<T> | actually touch, but they do so
+-----------+ +---------+ through a type generator which
minimizes the number of converters
that must be generated, so they
Each unwrap<T>, unwrap_more<T>, wrap<T>, wrap_more<T> converter holds
a reference to an appropriate converter object
This hierarchy contains converter body classes
Exposes use/release which
are needed in case the converter
+-----------+ in the registry needs to be
| converter | cloned. That occurs when a
+-----------+ unwrap target type is not
^ contained within the Python object.
|
+------------------+-----+
| |
+--------+-------+ Exposes |
| unwrapper_base | convertible() |
+----------------+ |
^ |
| |
+--------+----+ +-----+-----+
| unwrapper<T>| | wrapper<T>|
+-------------+ +-----------+
Exposes T convert(PyObject*) Exposes PyObject* convert(T)
unwrap:
constructed with a PyObject*, whose reference count is
incremented.
find the registry entry for the target type
look in the collection of converters for one which claims to be
able to convert the PyObject to the target type.
stick a pointer to the unwrapper in the unwrap object
when unwrap is queried for convertibility, it checks to see
if it has a pointer to an unwrapper.
on conversion, the unwrapper is asked to allocate an
implementation if the unwrap object isn't already holding
one. The unwrap object "takes ownership" of the unwrapper's
implementation. No memory allocation will actually take place
unless this is a value conversion.
on destruction, the unwrapper is asked to free any implementation
held by the unwrap object. No memory deallocation actually
takes place unless this is a value conversion
on destruction, the reference count on the held PyObject is
decremented.
We need to make sure that by default, you can't instantiate
callback<> for reference and pointer return types: although the
unwrappers may exist, they may convert by-value, which would cause
the referent to be destroyed upon return.
wrap:
find the registry entry for the source type
see if there is a converter. If found, stick a pointer to it in
the wrap object.
when queried for convertibility, it checks to see if it has a
pointer to a converter.
on conversion, a reference to the target PyObject is held by the
converter. Generally, the PyObject will have been created by the
converter, but in certain cases it may be a pre-existing object,
whose reference count will have been incremented.
when a wrap<T> x is used to return from a C++ function,
x.release() is returned so that x no longer holds a reference to
the PyObject when destroyed.
Otherwise, on destruction, any PyObject still held has its
reference-count decremented.
When a converter is created by the user, the appropriate element must
be added to the registry; when it is destroyed, it must be removed
from the registry.

View File

@@ -1,193 +1,98 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st September 2004), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="boost.css">
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python - News/Change Log</title>
</head>
<title>Boost.Python - News/Change Log</title>
</head>
<body link="#0000FF" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../boost.png" border="0"></a></h3>
</td>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">News/Change Log</h2>
</td>
</tr>
</table>
<hr>
<h2 align="center">News/Change Log</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt>Current CVS</dt>
<dl class="page-index">
<dt>19 November 2004 - 1.32 release</dt>
<dd>
<ul>
<li>C++ signatures are now automatically appended to the
docstrings.
<dd>
<ul>
<li>Updated to use the Boost Software License.</li>
<li>A new, <a href="tutorial/doc/html/python/exposing.html#python.class_virtual_functions">better method of wrapping classes with virtual functions</a> has been implemented.</li>
<li>Support for upcoming GCC symbol export control features have been folded in, thanks to Niall Douglas.</li>
<li>Improved support for <code>std::auto_ptr</code>-like types.</li>
<li>The Visual C++ bug that makes top-level <i>cv-qualification</i> of function parameter types part of the function type has been worked around.</li>
<li>Components used by other libraries have been moved out of <code>python/detail</code> and into <code> boost/detail</code> to improve dependency relationships.</li>
<li>Miscellaneous bug fixes and compiler workarounds.</li>
</ul>
</dd>
<dt>8 Sept 2004</dt>
<li>New <a href="v2/docstring_options.html"
><code>docstring_options.hpp</code></a> header to
control the content of docstrings.
<dd>
Support for Python's Bool type, thanks to <a
mailto="dholth-at-fastmail.fm">Daniel Holth</a>.
</dd>
<li>Support for converting <code>void*</code> to/from python,
with <code><a
href="v2/opaque.html">opaque_pointer_converter</a></code>
as the return value policy. Thanks to Niall Douglas for the
initial patch.
</ul>
</dd>
<dt>11 Sept 2003</dt>
<dt>19 October 2005 - 1.33.1 release</dt>
<dd>
<ul>
<li>Changed the response to multiple to-python converters being
registered for the same type from a hard error into warning;
Boost.Python now reports the offending type in the message.</li>
<dd>
<ul>
<li><code>wrapper&lt;T&gt;</code> can now be used as expected with a
held type of <i>some-smart-pointer</i><code>&lt;T&gt;</code></li>
<li>Added builtin <code>std::wstring</code> conversions</li>
<li>The build now assumes Python 2.4 by default, rather than 2.2</li>
<li>Added <code>std::out_of_range</code> =&gt; Python
<code>IndexError</code> exception conversion, thanks to <a href=
"mailto:RaoulGough-at-yahoo.co.uk">Raoul Gough</a></li>
</ul>
</dd>
<li>Support Python that's built without Unicode support</li>
<dt>9 Sept 2003</dt>
<li>Support for wrapping classes with overloaded address-of
(<code>&amp;</code>) operators</li>
</ul>
</dd>
<dd>Added new <code><a href="v2/str.html#str-spec">str</a></code></dd>
<dt>14 August 2005 - 1.33 release</dt>
<dt>constructors which take a range of characters, allowing strings
containing nul (<code>'\0'</code>) characters.</dt>
<dd>
<ul>
<li>Support for docstrings on nonstatic properties.</li>
<dt>8 Sept 2003</dt>
<li>We now export the client-provided docstrings for
<code>init&lt;optional&lt;&gt; &gt;</code> and
<i>XXX</i><code>_FUNCTION_OVERLOADS()</code> for only the last
overload.</li>
<dd>Added the ability to create methods from function objects (with an
<code>operator()</code>); see the <a href=
"v2/make_function.html#make_function-spec">make_function</a> docs for
more info.</dd>
<li>Fixed some support for Embedded VC++ 4</li>
<dt>10 August 2003</dt>
<li>Better support for rvalue from-python conversions of shared_ptr:
always return a pointer that holds the owning python object *unless*
the python object contains a NULL shared_ptr holder of the right
type.</li>
<dd>Added the new <code>properties</code> unit tests contributed by <a
href="mailto:romany-at-actimize.com">Roman Yakovenko</a> and documented
<code>add_static_property</code> at his urging.</dd>
<li>Support for exposing <code>vector&lt;T*&gt;</code> with the
indexing suite.</li>
<dt>1 August 2003</dt>
<li>Support for GCC-3.3 on MacOS.</li>
<li>updated visual studio project build file to include two new files
(slice.cpp and wrapper.cpp)</li>
<li>Added search feature to the index page.</li>
<li>Numerous fixes to the tutorial</li>
<li>Numerous workarounds for MSVC 6 and 7, GCC 2.96, and EDG
2.45</li>
</ul>
</dd>
<dt>11 March 2005</dt>
<dd>
<ul>
<li>Added a hack that will fool PyDoc into working with Boost.Python,
thanks to Nick Rasmussen</li>
</ul>
</dd>
<dt>19 November 2004 - 1.32 release</dt>
<dd>
<ul>
<li>Updated to use the Boost Software License.</li>
<li>A new, <a href=
"tutorial/doc/html/python/exposing.html#python.class_virtual_functions">
better method of wrapping classes with virtual functions</a> has been
implemented.</li>
<li>Support for upcoming GCC symbol export control features have been
folded in, thanks to Niall Douglas.</li>
<li>Improved support for <code>std::auto_ptr</code>-like types.</li>
<li>The Visual C++ bug that makes top-level <i>cv-qualification</i>
of function parameter types part of the function type has been worked
around.</li>
<li>Components used by other libraries have been moved out of
<code>python/detail</code> and into <code>boost/detail</code> to
improve dependency relationships.</li>
<li>Miscellaneous bug fixes and compiler workarounds.</li>
</ul>
</dd>
<dt>8 Sept 2004</dt>
<dd>Support for Python's Bool type, thanks to <a href=
"mailto:dholth-at-fastmail.fm">Daniel Holth</a>.</dd>
<dt>11 Sept 2003</dt>
<dd>
<ul>
<li>Changed the response to multiple to-python converters being
registered for the same type from a hard error into warning;
Boost.Python now reports the offending type in the message.</li>
<li>Added builtin <code>std::wstring</code> conversions</li>
<li>Added <code>std::out_of_range</code> =&gt; Python
<code>IndexError</code> exception conversion, thanks to <a href=
"mailto:RaoulGough-at-yahoo.co.uk">Raoul Gough</a></li>
</ul>
</dd>
<dt>9 Sept 2003</dt>
<dd>Added new <code><a href="v2/str.html#str-spec">str</a></code></dd>
<dt>constructors which take a range of characters, allowing strings
containing nul (<code>'\0'</code>) characters.</dt>
<dt>8 Sept 2003</dt>
<dd>Added the ability to create methods from function objects (with an
<code>operator()</code>); see the <a href=
"v2/make_function.html#make_function-spec">make_function</a> docs for
more info.</dd>
<dt>10 August 2003</dt>
<dd>Added the new <code>properties</code> unit tests contributed by
<a href="mailto:romany-at-actimize.com">Roman Yakovenko</a> and
documented <code>add_static_property</code> at his urging.</dd>
<dt>1 August 2003</dt>
<dd>
Added the new <code>arg</code> class contributed by <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a> which supplies the
ability to wrap functions that can be called with ommitted arguments in
the middle:
<pre>
<dd>
Added the new <code>arg</code> class contributed by <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a> which supplies the
ability to wrap functions that can be called with ommitted arguments
in the middle:
<pre>
void f(int x = 0, double y = 3.14, std::string z = std::string("foo"));
BOOST_PYTHON_MODULE(test)
@@ -196,104 +101,111 @@ BOOST_PYTHON_MODULE(test)
, (arg("x", 0), arg("y", 3.14), arg("z", "foo")));
}
</pre>And in Python:
<pre>
</pre>
And in Python:
<pre>
&gt;&gt;&gt; import test
&gt;&gt;&gt; f(0, z = "bar")
&gt;&gt;&gt; f(z = "bar", y = 0.0)
</pre>Thanks, Nikolay!
</dd>
</pre>
Thanks, Nikolay!
</dd>
<dt>22 July 2003</dt>
<dt>22 July 2003</dt>
<dd>Killed the dreaded "bad argument type for builtin operation" error.
Argument errors now show the actual and expected argument types!</dd>
<dd>Killed the dreaded "bad argument type for builtin operation" error.
Argument errors now show the actual and expected argument types!</dd>
<dt>19 July 2003</dt>
<dt>19 July 2003</dt>
<dd>Added the new <code><a href=
"v2/return_arg.html">return_arg</a></code> policy from <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a>. Thanks, Nikolay!</dd>
<dd>Added the new <code><a href=
"v2/return_arg.html">return_arg</a></code> policy from <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a>. Thanks,
Nikolay!</dd>
<dt>18 March, 2003</dt>
<dt>18 March, 2003</dt>
<dd><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
Gan&szlig;auge</a> has contributed <a href=
"v2/opaque.html">opaque pointer support</a>.<br>
<a href="mailto:nicodemus-at-globalite.com.br">Bruno da Silva de
Oliveira</a> has contributed the exciting <a href=
"../pyste/index.html">Pyste</a> ("Pie-steh") package.</dd>
<dd><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
Gan&szlig;auge</a> has contributed <a href=
"v2/opaque_pointer_converter.html">opaque pointer support</a>.<br>
<a href="mailto:nicodemus-at-globalite.com.br">Bruno da Silva de Oliveira</a>
has contributed the exciting <a href="../pyste/index.html">Pyste</a>
("Pie-steh") package.</dd>
<dt>24 February 2003</dt>
<dt>24 February 2003</dt>
<dd>Finished improved support for <code>boost::shared_ptr</code>. Now any
wrapped object of C++ class <code>X</code> can be converted automatically
to <code>shared_ptr&lt;X&gt;</code>, regardless of how it was wrapped.
The <code>shared_ptr</code> will manage the lifetime of the Python object
which supplied the <code>X</code>, rather than just the <code>X</code>
object itself, and when such a <code>shared_ptr</code> is converted back
to Python, the original Python object will be returned.</dd>
<dd>Finished improved support for <code>boost::shared_ptr</code>. Now
any wrapped object of C++ class <code>X</code> can be converted
automatically to <code>shared_ptr&lt;X&gt;</code>, regardless of how it
was wrapped. The <code>shared_ptr</code> will manage the lifetime of
the Python object which supplied the <code>X</code>, rather than just
the <code>X</code> object itself, and when such a
<code>shared_ptr</code> is converted back to Python, the original
Python object will be returned.</dd>
<dt>19 January 2003</dt>
<dt>19 January 2003</dt>
<dd>Integrated <code>staticmethod</code> support from <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a>. Thanks, Nikolay!</dd>
<dd>Integrated <code>staticmethod</code> support from <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a>. Thanks,
Nikolay!</dd>
<dt>29 December 2002</dt>
<dt>29 December 2002</dt>
<dd>Added Visual Studio project file and instructions from Brett Calcott.
Thanks, Brett!</dd>
<dd>Added Visual Studio project file and instructions from Brett
Calcott. Thanks, Brett!</dd>
<dt>20 December 2002</dt>
<dt>20 December 2002</dt>
<dd>Added automatic downcasting for pointers, references, and smart
pointers to polymorphic class types upon conversion to python</dd>
<dd>Added automatic downcasting for pointers, references, and smart
pointers to polymorphic class types upon conversion to python</dd>
<dt>18 December 2002</dt>
<dt>18 December 2002</dt>
<dd>Optimized from_python conversions for wrapped classes by putting the
conversion logic in the shared library instead of registering separate
converters for each class in each extension module</dd>
<dd>Optimized from_python conversions for wrapped classes by putting
the conversion logic in the shared library instead of registering
separate converters for each class in each extension module</dd>
<dt>19 November 2002</dt>
<dt>19 November 2002</dt>
<dd>Removed the need for users to cast base class member function
pointers when used as arguments to <a href=
"v2/class.html#class_-spec-modifiers">add_property</a></dd>
<dd>Removed the need for users to cast base class member function
pointers when used as arguments to <a href=
"v2/class.html#class_-spec-modifiers">add_property</a></dd>
<dt>13 December 2002</dt>
<dt>13 December 2002</dt>
<dd>Allow exporting of <a href=
"v2/enum.html#enum_-spec"><code>enum_</code></a> values into enclosing
<a href="v2/scope.html#scope-spec"><code>scope</code></a>.<br>
Fixed unsigned integer conversions to deal correctly with numbers that
are out-of-range of <code>signed long</code>.</dd>
<dd>Allow exporting of <a href=
"v2/enum.html#enum_-spec"><code>enum_</code></a> values into enclosing
<a href="v2/scope.html#scope-spec"><code>scope</code></a>.<br>
Fixed unsigned integer conversions to deal correctly with numbers that
are out-of-range of <code>signed long</code>.</dd>
<dt>14 November 2002</dt>
<dt>14 November 2002</dt>
<dd>Auto-detection of class data members wrapped with <a href=
"v2/data_members.html#make_getter-spec"><code>make_getter</code></a></dd>
<dd>Auto-detection of class data members wrapped with <a href=
"v2/data_members.html#make_getter-spec"><code>make_getter</code></a></dd>
<dt>13 November 2002</dt>
<dt>13 November 2002</dt>
<dd>Full Support for <code>std::auto_ptr&lt;&gt;</code> added.</dd>
<dd>Full Support for <code>std::auto_ptr&lt;&gt;</code> added.</dd>
<dt>October 2002</dt>
<dt>October 2002</dt>
<dd>Ongoing updates and improvements to tutorial documentation</dd>
<dd>Ongoing updates and improvements to tutorial documentation</dd>
<dt>10 October 2002</dt>
<dt>10 October 2002</dt>
<dd>Boost.Python V2 is released!</dd>
</dl>
<hr>
<dd>Boost.Python V2 is released!</dd>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
19 November 2004
<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
19 November 2004
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003.</i></p>
</body>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003.</i></p>
</body>
</html>

View File

@@ -1,8 +1,3 @@
.. Copyright David Abrahams 2006. 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)
How Runtime Polymorphism is expressed in Boost.Python:
-----------------------------------------------------

View File

@@ -1,445 +1,390 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st September 2004), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python - Projects using Boost.Python</title>
</head>
<body link="#0000FF" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">Projects using Boost.Python</h2>
</td>
</tr>
</table>
<hr>
<h2>Introduction</h2>
<p>This is a partial list of projects using Boost.Python. If you are using
Boost.Python as your Python/C++ binding solution, we'd be proud to list
your project on this page. Just <a href=
"mailto:c++-sig@python.org">post</a> a short description of your project
and how Boost.Python helps you get the job done, and we'll add it to this
page .</p>
<hr>
<h3>Data Analysis</h3>
<dl class="page-index">
<dt><b><a href="http://www.neuralynx.com">NeuraLab</a></b></dt>
<dd>Neuralab is a data analysis environment specifically tailored for
neural data from <a href="http://www.neuralynx.com">Neuralynx</a>
acquisition systems. Neuralab combines presentation quality graphics, a
numerical analysis library, and the <a href=
"http://www.python.org">Python</a> scripting engine in a single
application. With Neuralab, Neuralynx users can perform common analysis
tasks with just a few mouse clicks. More advanced users can create custom
Python scripts, which can optionally be assigned to menus and mouse
clicks.</dd>
</dl>
<dl class="page-index">
<dt><b>TSLib</b> - <a href="http://www.fortressinv.com">Fortress
Investment Group LLC</a></dt>
<dd>
Fortress Investment Group has contracted <a href=
"http://www.boost-consulting.com">Boost Consulting</a> to develop core
internal financial analysis tools in C++ and to prepare Python bindings
for them using Boost.Python.
<p>Tom Barket of Fortress writes:</p>
<blockquote>
We have a large C++ analytical library specialized for research in
finance and economics, built for speed and mission critical
stability. Yet Python offers us the flexibility to test out new ideas
quickly and increase the productivity of our time versus working in
C++. There are several key features which make Python stand out. Its
elegance, stability, and breadth of resources on the web are all
valuable, but the most important is its extensibility, due to its
open source transparency. Boost.Python makes Python extensibility
extremely simple and straightforward, yet preserves a great deal of
power and control.
</blockquote>
</dd>
</dl>
<h3>Educational</h3>
<dl class="page-index">
<dt><a href="http://edu.kde.org/kig"><b>Kig</b></a></dt>
<dd>
<p>KDE Interactive Geometry is a high-school level educational tool,
built for the KDE desktop. It is a nice tool to let students work with
geometrical constructions. It is meant to be the most intuitive, yet
featureful application of its kind.</p>
<p>Versions after 0.6.x (will) support objects built by the user
himself in the Python language. The exporting of the relevant internal
API's were done using Boost.Python, which made the process very
easy.</p>
</dd>
</dl>
<h3>Enterprise Software</h3>
<dl class="page-index">
<dt><b><a href="http://openwbem.sourceforge.net">OpenWBEM</a></b></dt>
<dd>
The OpenWBEM project is an effort to develop an open-source
implementation of Web Based Enterprise Management suitable for
commercial and non-commercial application
<p><a href="mailto:dnuffer@sco.com">Dan Nuffer</a> writes:</p>
<blockquote>
I'm using Boost.Python to wrap the client API of OpenWBEM.This will
make it easier to do rapid prototyping, testing, and scripting when
developing management solutions that use WBEM.
</blockquote>
</dd>
<dt><b><a href="http://www.transversal.com">Metafaq</a></b></dt>
<dd>
Metafaq, from <a href="http://www.transversal.com">Transversal,
Inc.</a>, is an enterprise level online knowledge base management
system.
<p><a href="mailto:ben.young-at-transversal.com">Ben Young</a>
writes:</p>
<blockquote>
Boost.Python is used in an automated process to generate python
bindings to our api which is exposed though multiple backends and
frontends. This allows us to write quick tests and bespoke scripts to
perform one off tasks without having to go through the full
compilation cycle.
</blockquote>
</dd>
</dl>
<h3>Games</h3>
<dl>
<dt><b><a href="http://www.firaxis.com">Civilization IV</a></b></dt>
</dl>
<blockquote>
&ldquo;The fourth game in the PC strategy series that has sold over five
million copies, Sid Meier's Civilization IV is a bold step forward for
the franchise, with spectacular new 3D graphics and all-new single and
multiplayer content. Civilization IV will also set a new standard for
user-modification, allowing gamers to create their own add-ons using
Python and XML.
<p>Sid Meier's Civilization IV will be released for PC in late 2005. For
more information please visit <a href=
"http://www.firaxis.com">http://www.firaxis.com</a> or write <a href=
"mailto:kgilmore@firaxis.com">kgilmore@firaxis.com</a>&rdquo;</p>
</blockquote>
<p>Boost.Python is used as the interface layer between the C++ game code
and Python. Python is used for many purposes in the game, including map
generation, interface screens, game events, tools, tutorials, etc. Most
high-level game operations have been exposed to Python in order to give
modders the power they need to customize the game.</p>
<blockquote>
-Mustafa Thamer, Civ4 Lead Programmer
</blockquote>
<dl class="page-index">
<dt><b><a href="http://vegastrike.sourceforge.net">Vega
Strike</a></b></dt>
<dd>
<a href="http://vegastrike.sourceforge.net">Vega Strike</a> is the 3D
Space Simulator that allows you to trade and bounty hunt in a vast
universe. Players face dangers, decisions, piracy, and aliens.
<p><a href="http://vegastrike.sourceforge.net">Vega Strike</a> has
decided to base its scripting on python, using boost as the layer
between the class hierarchy in python and the class hierarchy in C++.
The result is a very flexible scripting system that treats units as
native python classes when designing missions or writing AI's.</p>
<p>A large economic and planetary simulation is currently being run in
the background in python and the results are returned back into C++ in
the form of various factions' spaceships appearing near worlds that
they are simulated to be near in python if the player is in the general
neighborhood.</p>
</dd>
</dl>
<h3>Graphics</h3>
<dl class="page-index">
<dt><b><a href="http://sourceforge.net/projects/pyosg">OpenSceneGraph
Bindings</a></b></dt>
<dd><a href="mailto:gideon@computer.org">Gideon May</a> has created a set
of bindings for <a href=
"http://www.openscenegraph.org">OpenSceneGraph</a>, a cross-platform
C++/OpenGL library for the real-time visualization.<br>
&nbsp;</dd>
<dt><b><a href=
"http://www.slac.stanford.edu/grp/ek/hippodraw/index.html">HippoDraw</a></b></dt>
<dd>
HippoDraw is a data analysis environment consisting of a canvas upon
which graphs such as histograms, scattter plots, etc, are prsented. It
has a highly interactive GUI interface, but some things you need to do
with scripts. HippoDraw can be run as Python extension module so that
all the manipulation can be done from either Python or the GUI.
<p>Before the web page came online, <a href=
"mailto:Paul_Kunz@SLAC.Stanford.EDU">Paul F. Kunz</a> wrote:</p>
<blockquote>
Don't have a web page for the project, but the organization's is
<a href=
"http://www.slac.stanford.edu">http://www.slac.stanford.edu</a> (the
first web server site in America, I installed it).
</blockquote>Which was just too cool a piece of trivia to omit.<br>
&nbsp;
</dd>
<dt><a href="http://www.iplt.org"><b>IPLT</b></a></dt>
<dd>
<a href="mailto:ansgar.philippsen-at-unibas.ch">Ansgar Philippsen</a>
writes:
<blockquote>
IPLT is an image processing library and toolbox for the structural
biology electron microscopy community. I would call it a
budding/evolving project, since it is currently not in production
stage, but rather under heavy development. Python is used as the main
scripting/interaction level, but also for rapid prototyping, since
the underlying C++ class library is pretty much fully exposed via
boost.python (at least the high-level interface). The combined power
of C++ and Python for this project turned out to be just awesome.
</blockquote><br>
&nbsp;
</dd>
<dt><a href=
"http://www.procoders.net/pythonmagick"><b>PythonMagick</b></a></dt>
<dd>PythonMagick binds the <a href=
"http://www.graphicsmagick.org">GraphicsMagick</a> image manipulation
library to Python.<br>
&nbsp;</dd>
<dt><a href="http://www.vpython.org"><b>VPython</b></a></dt>
<dd>
<a href="mailto:Bruce_Sherwood-at-ncsu.edu">Bruce Sherwood</a> writes:
<blockquote>
VPython is an extension for Python that makes it easy to create
navigable 3D animations, which are generated as a side effect of
computational code. VPython is used in education for various
purposes, including teaching physics and programming, but it has also
been used by research scientists to visualize systems or data in 3D.
</blockquote><br>
&nbsp;
</dd>
</dl>
<h3>Scientific Computing</h3>
<dl class="page index">
<dt><a href="http://camfr.sourceforge.net"><b>CAMFR</b></a></dt>
<dd>
CAMFR is a photonics and electromagnetics modelling tool. Python is
used for computational steering.
<p><a href="mailto:Peter.Bienstman@rug.ac.be">Peter Bienstman</a>
writes:</p>
<blockquote>
Thanks for providing such a great tool!
</blockquote>
</dd>
<dt><a href="http://cctbx.sourceforge.net"><b>cctbx - Computational
Crystallography Toolbox</b></a></dt>
<dd>
Computational Crystallography is concerned with the derivation of
atomic models of crystal structures, given experimental X-ray
diffraction data. The cctbx is an open-source library of fundamental
algorithms for crystallographic computations. The core algorithms are
implemented in C++ and accessed through higher-level Python interfaces.
<p>The cctbx grew together with Boost.Python and is designed from the
ground up as a hybrid Python/C++ system. With one minor exception,
run-time polymorphism is completely handled by Python. C++ compile-time
polymorphism is used to implement performance critical algorithms. The
Python and C++ layers are seamlessly integrated using Boost.Python.</p>
<p>The SourceForge cctbx project is organized in modules to facilitate
use in non-crystallographic applications. The scitbx module implements
a general purpose array family for scientific applications and pure C++
ports of FFTPACK and the L-BFGS quasi-Newton minimizer.</p>
</dd>
<dt><a href="http://www.llnl.gov/CASC/emsolve"><b>EMSolve</b></a></dt>
<dd>EMSolve is a provably stable, charge conserving, and energy
conserving solver for Maxwell's equations.<br>
&nbsp;</dd>
<dt><b><a href="http://cern.ch/gaudi">Gaudi</a></b> and <b><a href=
"http://cern.ch/Gaudi/RootPython/">RootPython</a></b></dt>
<dd>
Gaudi is a framework for particle physics collision data processing
applications developed in the context of the LHCb and ATLAS experiments
at CERN.
<p><a href="mailto:Pere.Mato@cern.ch">Pere Mato Vila</a> writes:</p>
<blockquote>
We are using Boost.Python to provide scripting/interactive capability
to our framework. We have a module called "GaudiPython" implemented
using Boost.Python that allows the interaction with any framework
service or algorithm from python. RootPython also uses Boost.Python
to provide a generic "gateway" between the <a href=
"http://root.cern.ch">ROOT</a> framework and python
<p>Boost.Python is great. We managed very quickly to interface our
framework to python, which is great language. We are trying to
facilitate to our physicists (end-users) a rapid analysis application
development environment based on python. For that, Boost.Python plays
and essential role.</p>
</blockquote>
</dd>
<dt><b><a href="http://www.esss.com.br">ESSS</a></b></dt>
<dd>
ESSS (Engineering Simulation and Scientific Software) is a company that
provides engineering solutions and acts in the brazilian and
south-american market providing products and services related to
Computational Fluid Dynamics and Image Analysis.
<p><a href="mailto:bruno@esss.com.br">Bruno da Silva de Oliveira</a>
writes:</p>
<blockquote>
Recently we moved our work from working exclusively with C++ to an
hybrid-language approach, using Python and C++, with Boost.Python
providing the layer between the two. The results are great so far!
</blockquote>
<p>Two projects have been developed so far with this technology:</p>
<p><b><a href=
"http://www.esss.com.br/index.php?pg=dev_projetos">Simba</a></b>
provides 3D visualization of geological formations gattered from the
simulation of the evolution of oil systems, allowing the user to
analyse various aspects of the simulation, like deformation, pressure
and fluids, along the time of the simulation.</p>
<p><b><a href=
"http://www.esss.com.br/index.php?pg=dev_projetos">Aero</a></b> aims to
construct a CFD with brazilian technology, which involves various
companies and universities. ESSS is responsible for various of the
application modules, including GUI and post-processing of results.</p>
</dd>
<dt><b><a href="http://www.rationaldiscovery.com">Rational Discovery
LLC</a></b></dt>
<dd>
Rational Discovery provides computational modeling, combinatorial
library design and custom software development services to the
pharmaceutical, biotech and chemical industries. We do a substantial
amount of internal research to develop new approaches for applying
machine-learning techniques to solve chemical problems. Because we're a
small organization and chemistry is a large and complex field, it is
essential that we be able to quickly and easily prototype and test new
algorithms.
<p>For our internal software, we implement core data structures in C
and expose them to Python using Boost.Python. Algorithm development is
done in Python and then translated to C if required (often it's not).
This hybrid development approach not only greatly increases our
productivity, but it also allows "non-developers" (people without C
experience) to take part in method development. Learning C is a
daunting task, but "Python fits your brain." (Thanks to Bruce Eckel for
the quote.)</p>
</dd>
</dl>
<h3>Systems Libraries</h3>
<dl>
<dt><a href="http://itamarst.org/software"><b>Fusion</b></a></dt>
<dd>
<p>Fusion is a library that supports implementing protocols in C++ for
use with Twisted, allowing control over memory allocation strategies,
fast method calls internally, etc.. Fusion supports TCP, UDP and
multicast, and is implemented using the Boost.Python python
bindings.</p>
<p>Fusion is licensed under the MIT license, and available for download
from <a href=
"http://itamarst.org/software">http://itamarst.org/software</a>.</p>
</dd>
</dl>
<h3>Tools</h3>
<dl>
<dt><a href="http://www.jayacard.org"><b>Jayacard</b></a></dt>
<dd>
Jayacard aims at developing a secure portable open source operating
system for contactless smart cards and a complete suite of high quality
development tools to ease smart card OS and application development.
<p>The core of the smart card reader management is written in C++ but
all the development tools are written in the friendly Python language.
Boost plays the fundamental role of binding the tools to our core smart
card reader library.</p>
</dd>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
15 July, 2003</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003.</i></p>
</body>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python - Projects using Boost.Python</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">Projects using Boost.Python</h2>
</td>
</tr>
</table>
<hr>
<h2>Introduction</h2>
<p>This is a partial list of projects using Boost.Python. If you are
using Boost.Python as your Python/C++ binding solution, we'd be proud to
list your project on this page. Just <a href=
"mailto:c++-sig@python.org">post</a> a short description of your project
and how Boost.Python helps you get the job done, and we'll add it to this
page .</p>
<hr>
<h3>Data Analysis</h3>
<dl class="page-index">
<dt><b><a href=
"http://www.neuralynx.com/neuralab/index.htm">NeuraLab</a></b></dt>
<dd>Neuralab is a data analysis environment specifically tailored for
neural data from <a href="http://www.neuralynx.com">Neuralynx</a>
acquisition systems. Neuralab combines presentation quality graphics, a
numerical analysis library, and the <a href=
"http://www.python.org">Python</a> scripting engine in a single
application. With Neuralab, Neuralynx users can perform common analysis
tasks with just a few mouse clicks. More advanced users can create
custom Python scripts, which can optionally be assigned to menus and
mouse clicks.</dd>
</dl>
<dl class="page-index">
<dt><b>TSLib</b> - <a href="http://www.fortressinv.com">Fortress
Investment Group LLC</a></dt>
<dd>
Fortress Investment Group has contracted <a href=
"http://www.boost-consulting.com">Boost Consulting</a> to develop
core internal financial analysis tools in C++ and to prepare Python
bindings for them using Boost.Python.
<p>Tom Barket of Fortress writes:</p>
<blockquote>
We have a large C++ analytical library specialized for research in
finance and economics, built for speed and mission critical
stability. Yet Python offers us the flexibility to test out new
ideas quickly and increase the productivity of our time versus
working in C++. There are several key features which make Python
stand out. Its elegance, stability, and breadth of resources on the
web are all valuable, but the most important is its extensibility,
due to its open source transparency. Boost.Python makes Python
extensibility extremely simple and straightforward, yet preserves a
great deal of power and control.
</blockquote>
</dd>
</dl>
<h3>Educational</h3>
<dl class="page-index">
<dt><a href="http://edu.kde.org/kig"><b>Kig</b></a></dt>
<dd>
<p>KDE Interactive Geometry is a high-school level educational tool,
built for the KDE desktop. It is a nice tool to let students work
with geometrical constructions. It is meant to be the most intuitive,
yet featureful application of its kind.</p>
<p>Versions after 0.6.x (will) support objects built by the user
himself in the Python language. The exporting of the relevant
internal API's were done using Boost.Python, which made the process
very easy.</p>
</dd>
</dl>
<h3>Enterprise Software</h3>
<dl class="page-index">
<dt><b><a href="http://openwbem.sourceforge.net">OpenWBEM</a></b></dt>
<dd>
The OpenWBEM project is an effort to develop an open-source
implementation of Web Based Enterprise Management suitable for
commercial and non-commercial application
<p><a href="mailto:dnuffer@sco.com">Dan Nuffer</a> writes:</p>
<blockquote>
I'm using Boost.Python to wrap the client API of OpenWBEM.This will
make it easier to do rapid prototyping, testing, and scripting when
developing management solutions that use WBEM.
</blockquote>
</dd>
<dt><b><a href="http://www.transversal.com">Metafaq</a></b></dt>
<dd>
Metafaq, from <a href="http://www.transversal.com">Transversal,
Inc.</a>, is an enterprise level online knowledge base management
system.
<p><a href="mailto:ben.young-at-transversal.com">Ben Young</a>
writes:</p>
<blockquote>
Boost.Python is used in an automated process to generate python
bindings to our api which is exposed though multiple backends and
frontends. This allows us to write quick tests and bespoke scripts
to perform one off tasks without having to go through the full
compilation cycle.
</blockquote>
</dd>
</dl>
<h3>Games</h3>
<dl class="page-index">
<dt><b><a href="http://vegastrike.sourceforge.net">Vega
Strike</a></b></dt>
<dd>
<a href="http://vegastrike.sourceforge.net">Vega Strike</a> is the 3D
Space Simulator that allows you to trade and bounty hunt in a vast
universe. Players face dangers, decisions, piracy, and aliens.
<p><a href="http://vegastrike.sourceforge.net">Vega Strike</a> has
decided to base its scripting on python, using boost as the layer
between the class hierarchy in python and the class hierarchy in C++.
The result is a very flexible scripting system that treats units as
native python classes when designing missions or writing AI's.</p>
<p>A large economic and planetary simulation is currently being run
in the background in python and the results are returned back into
C++ in the form of various factions' spaceships appearing near worlds
that they are simulated to be near in python if the player is in the
general neighborhood.</p>
</dd>
</dl>
<h3>Graphics</h3>
<dl class="page-index">
<dt><b><a href="http://sourceforge.net/projects/pyosg">OpenSceneGraph
Bindings</a></b></dt>
<dd><a href="mailto:gideon@computer.org">Gideon May</a> has created a
set of bindings for <a href=
"http://www.openscenegraph.org">OpenSceneGraph</a>, a cross-platform
C++/OpenGL library for the real-time visualization.<br>
&nbsp;</dd>
<dt><b><a href=
"http://www.slac.stanford.edu/grp/ek/hippodraw/index.html">HippoDraw</a></b></dt>
<dd>
HippoDraw is a data analysis environment consisting of a canvas upon
which graphs such as histograms, scattter plots, etc, are prsented.
It has a highly interactive GUI interface, but some things you need
to do with scripts. HippoDraw can be run as Python extension module
so that all the manipulation can be done from either Python or the
GUI.
<p>Before the web page came online, <a href=
"mailto:Paul_Kunz@SLAC.Stanford.EDU">Paul F. Kunz</a> wrote:</p>
<blockquote>
Don't have a web page for the project, but the organization's is <a
href=
"http://www.slac.stanford.edu">http://www.slac.stanford.edu</a>
(the first web server site in America, I installed it).
</blockquote>
Which was just too cool a piece of trivia to omit.<br>
&nbsp;
</dd>
<dt><a href="http://www.iplt.org"><b>IPLT</b></a></dt>
<dd>
<a href="mailto:ansgar.philippsen-at-unibas.ch">Ansgar
Philippsen</a> writes:
<blockquote>
IPLT is an image processing library and toolbox for the structural
biology electron microscopy community. I would call it a
budding/evolving project, since it is currently not in production
stage, but rather under heavy development. Python is used as the
main scripting/interaction level, but also for rapid prototyping,
since the underlying C++ class library is pretty much fully exposed
via boost.python (at least the high-level interface). The combined
power of C++ and Python for this project turned out to be just
awesome.
</blockquote>
<br>
&nbsp;
</dd>
<dt><a href=
"http://www.procoders.net/pythonmagick"><b>PythonMagick</b></a></dt>
<dd>PythonMagick binds the <a href=
"http://www.graphicsmagick.org">GraphicsMagick</a> image manipulation
library to Python.<br>
&nbsp;</dd>
</dl>
<h3>Scientific Computing</h3>
<dl class="page index">
<dt><a href="http://camfr.sourceforge.net"><b>CAMFR</b></a></dt>
<dd>
CAMFR is a photonics and electromagnetics modelling tool. Python is
used for computational steering.
<p><a href="mailto:Peter.Bienstman@rug.ac.be">Peter Bienstman</a>
writes:</p>
<blockquote>
Thanks for providing such a great tool!
</blockquote>
</dd>
<dt><a href="http://cctbx.sourceforge.net"><b>cctbx - Computational
Crystallography Toolbox</b></a></dt>
<dd>
Computational Crystallography is concerned with the derivation of
atomic models of crystal structures, given experimental X-ray
diffraction data. The cctbx is an open-source library of fundamental
algorithms for crystallographic computations. The core algorithms are
implemented in C++ and accessed through higher-level Python
interfaces.
<p>The cctbx grew together with Boost.Python and is designed from the
ground up as a hybrid Python/C++ system. With one minor exception,
run-time polymorphism is completely handled by Python. C++
compile-time polymorphism is used to implement performance critical
algorithms. The Python and C++ layers are seamlessly integrated using
Boost.Python.</p>
<p>The SourceForge cctbx project is organized in modules to
facilitate use in non-crystallographic applications. The scitbx
module implements a general purpose array family for scientific
applications and pure C++ ports of FFTPACK and the LBFGS conjugate
gradient minimizer.</p>
</dd>
<dt><a href="http://www.llnl.gov/CASC/emsolve"><b>EMSolve</b></a></dt>
<dd>EMSolve is a provably stable, charge conserving, and energy
conserving solver for Maxwell's equations.<br>
&nbsp;</dd>
<dt><b><a href="http://cern.ch/gaudi">Gaudi</a></b> and <b><a href=
"http://cern.ch/Gaudi/RootPython/">RootPython</a></b></dt>
<dd>
Gaudi is a framework for particle physics collision data processing
applications developed in the context of the LHCb and ATLAS
experiments at CERN.
<p><a href="mailto:Pere.Mato@cern.ch">Pere Mato Vila</a> writes:</p>
<blockquote>
We are using Boost.Python to provide scripting/interactive
capability to our framework. We have a module called "GaudiPython"
implemented using Boost.Python that allows the interaction with any
framework service or algorithm from python. RootPython also uses
Boost.Python to provide a generic "gateway" between the <a href=
"http://root.cern.ch">ROOT</a> framework and python
<p>Boost.Python is great. We managed very quickly to interface our
framework to python, which is great language. We are trying to
facilitate to our physicists (end-users) a rapid analysis
application development environment based on python. For that,
Boost.Python plays and essential role.</p>
</blockquote>
</dd>
<dt><b><a href="http://www.esss.com.br">ESSS</a></b></dt>
<dd>
ESSS (Engineering Simulation and Scientific Software) is a company
that provides engineering solutions and acts in the brazilian and
south-american market providing products and services related to
Computational Fluid Dynamics and Image Analysis.
<p><a href="mailto:bruno@esss.com.br">Bruno da Silva de Oliveira</a>
writes:</p>
<blockquote>
Recently we moved our work from working exclusively with C++ to an
hybrid-language approach, using Python and C++, with Boost.Python
providing the layer between the two. The results are great so far!
</blockquote>
<p>Two projects have been developed so far with this technology:</p>
<p><b><a href="http://www.esss.com.br/dev_simba.phtml">Simba</a></b>
provides 3D visualization of geological formations gattered from the
simulation of the evolution of oil systems, allowing the user to
analyse various aspects of the simulation, like deformation, pressure
and fluids, along the time of the simulation.</p>
<p><b><a href="http://www.esss.com.br/dev_aero.phtml">Aero</a></b>
aims to construct a CFD with brazilian technology, which involves
various companies and universities. ESSS is responsible for various
of the application modules, including GUI and post-processing of
results.</p>
</dd>
<dt><b><a href="http://www.rationaldiscovery.com">Rational Discovery
LLC</a></b></dt>
<dd>
Rational Discovery provides computational modeling, combinatorial
library design and custom software development services to the
pharmaceutical, biotech and chemical industries. We do a substantial
amount of internal research to develop new approaches for applying
machine-learning techniques to solve chemical problems. Because we're
a small organization and chemistry is a large and complex field, it
is essential that we be able to quickly and easily prototype and test
new algorithms.
<p>For our internal software, we implement core data structures in C
and expose them to Python using Boost.Python. Algorithm development
is done in Python and then translated to C if required (often it's
not). This hybrid development approach not only greatly increases our
productivity, but it also allows "non-developers" (people without C
experience) to take part in method development. Learning C is a
daunting task, but "Python fits your brain." (Thanks to Bruce Eckel
for the quote.)</p>
</dd>
</dl>
<h3>Tools</h3>
<dl>
<dt><a href="http://www.jayacard.org"><b>Jayacard</b></a></dt>
<dd>
Jayacard aims at developing a secure portable open source operating
system for contactless smart cards and a complete suite of high
quality development tools to ease smart card OS and application
development.
<p>The core of the smart card reader management is written in C++ but
all the development tools are written in the friendly Python
language. Boost plays the fundamental role of binding the tools to
our core smart card reader library.</p>
</dd>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
15 July, 2003</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003. </i></p>
</body>
</html>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,15 +1,8 @@
# Copyright Joel de Guzman 2006. 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)
project boost/libs/python/doc/tutorial/doc ;
import boostbook : boostbook ;
using quickbook ;
boostbook tutorial
:
tutorial.qbk
:
<xsl:param>boost.root=../../../../../..
<xsl:param>boost.libraries=../../../../../../libs/libraries.htm
boostbook tutorial : tutorial.xml
: <xsl:param>boost.root=../../../../../..
<xsl:param>boost.libraries=../../../../../libraries.htm
;

View File

@@ -0,0 +1,9 @@
index.html
python/hello.html
python/exposing.html
python/functions.html
python/object.html
python/embedding.html
python/iterators.html
python/exception.html
python/techniques.html

View File

@@ -1,5 +1,5 @@
/*=============================================================================
Copyright (c) 2004 Joel de Guzman
Copyright (c) 2002 2004 Joel de Guzman
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
@@ -7,505 +7,289 @@
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
/*=============================================================================
Body defaults
=============================================================================*/
/* CSS based on w3c documentation which I like a lot, and the classic Spirit
documentation. */
body
/* Body defaults */
body
{
padding: 2em 1em 2em 1em;
margin: 1em 1em 1em 1em;
font-family: sans-serif;
}
/* Paragraphs */
p
{
text-align: justify;
}
pre.synopsis
{
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
/* Headings */
h1, h2, h3, h4, h5, h6 { text-align: left; margin-top: 2pc; }
h1 { font: 170% sans-serif }
h2 { font: bold 140% sans-serif }
h3 { font: 120% sans-serif }
h4 { font: bold 100% sans-serif }
h5 { font: italic 100% sans-serif }
h6 { font: italic 100% sans-serif }
/* Unordered lists */
ul
{
text-align: justify;
}
/* Links */
a
{
text-decoration: none; /* no underline */
}
a:hover
{
text-decoration: underline;
}
/* Top page title */
title, h1.title, h2.title, h3.title,
h4.title, h5.title, h6.title,
.refentrytitle
{
font-weight: bold;
font-size: 2pc;
margin-bottom: 1pc;
}
/* Spirit style navigation */
.spirit-nav
{
text-align: right;
}
.spirit-nav a
{
color: white;
padding-left: 0.5em;
}
.spirit-nav img
{
border-width: 0px;
}
/* Program listing box */
.programlisting, .screen
{
display: block;
margin-left: 4%;
margin-right: 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
/* Table of contents */
.toc
{
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
.boost-toc
{
float: right;
padding: 0.5pc;
}
/* Tables */
.table-title, div.table p.title
{
margin-left: 4%;
padding-right: 0.5em;
padding-left: 0.5em;
font-size: 120%;
}
.informaltable table, .table table
{
width: 92%;
margin-left: 4%;
margin-right: 4%;
}
div.informaltable table, div.table table
{
padding: 4px 4px 4px 4px;
}
div.informaltable table tr td, div.table table tr td
{
padding: 0.5em 0.5em 0.5em 0.5em;
text-align: justify;
}
div.informaltable table tr th, div.table table tr th
{
padding: 0.5em 0.5em 0.5em 0.5em;
border: 1pt solid white;
}
/* inlined images */
.inlinemediaobject
{
padding: 0.5em 0.5em 0.5em 0.5em;
}
/* tone down the title of Parameter lists */
div.variablelist p.title
{
font-weight: bold;
font-size: 100%;
text-align: left;
}
/* tabularize parameter lists */
div.variablelist dl dt
{
float: left;
clear: left;
display: block;
font-style: italic;
}
div.variablelist dl dd
{
display: block;
clear: right;
padding-left: 8pc;
}
/* title of books and articles in bibliographies */
span.title
{
font-style: italic;
}
@media screen
{
a
{
margin: 1em;
font-family: sans-serif;
color: #005a9c;
}
/*=============================================================================
Paragraphs
=============================================================================*/
p
a:visited
{
text-align: left;
font-size: 10pt;
line-height: 1.15;
color: #9c5a9c;
}
/*=============================================================================
Program listings
=============================================================================*/
/* Syntax Highlighting */
.keyword { color: #0000AA; font-weight: bold; }
.identifier {}
.special { color: #707070; }
.preprocessor { color: #402080; font-weight: bold; }
.char { color: teal; }
.comment { color: #800000; }
.string { color: teal; }
.number { color: teal; }
.copyright { color: #666666; font-size: small; }
.white_bkd { background-color: #FFFFFF; }
.dk_grey_bkd { background-color: #999999; }
/* Code on paragraphs */
p tt.computeroutput
pre.synopsis
{
font-size: 9pt;
background-color: #f3f3f3;
}
.programlisting, .screen
{
background-color: #f3f3f3;
}
/* Table of contents */
.toc
{
background-color: #f3f3f3;
}
div.informaltable table tr td, div.table table tr td
{
background-color: #F3F3F3;
border: 1pt solid white;
}
div.informaltable table tr th, div.table table tr th
{
background-color: #e4e4e4;
}
span.highlight
{
color: #00A000;
}
}
@media print
{
a
{
color: black;
}
a:visited
{
color: black;
}
.spirit-nav
{
display: none;
}
/* Syntax Highlighting */
.keyword
{
font-weight: bold;
}
pre.synopsis
{
font-size: 90%;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
border: 1px solid gray;
}
.programlisting,
.screen
.programlisting, .screen
{
font-size: 9pt;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
border: 1px solid gray;
}
/* Program listings in tables don't get borders */
td .programlisting,
td .screen
{
margin: 0pc 0pc 0pc 0pc;
padding: 0pc 0pc 0pc 0pc;
}
/*=============================================================================
Headings
=============================================================================*/
h1, h2, h3, h4, h5, h6
{
text-align: left;
margin: 1em 0em 0.5em 0em;
font-weight: bold;
}
h1 { font: 140% }
h2 { font: bold 140% }
h3 { font: bold 130% }
h4 { font: bold 120% }
h5 { font: italic 110% }
h6 { font: italic 100% }
/* Top page titles */
title,
h1.title,
h2.title
h3.title,
h4.title,
h5.title,
h6.title,
.refentrytitle
{
font-weight: bold;
margin-bottom: 1pc;
}
h1.title { font-size: 140% }
h2.title { font-size: 140% }
h3.title { font-size: 130% }
h4.title { font-size: 120% }
h5.title { font-size: 110% }
h6.title { font-size: 100% }
.section h1
{
margin: 0em 0em 0.5em 0em;
font-size: 140%;
}
.section h2 { font-size: 140% }
.section h3 { font-size: 130% }
.section h4 { font-size: 120% }
.section h5 { font-size: 110% }
.section h6 { font-size: 100% }
/* Code on titles */
h1 tt.computeroutput { font-size: 140% }
h2 tt.computeroutput { font-size: 140% }
h3 tt.computeroutput { font-size: 130% }
h4 tt.computeroutput { font-size: 120% }
h5 tt.computeroutput { font-size: 110% }
h6 tt.computeroutput { font-size: 100% }
/*=============================================================================
Author
=============================================================================*/
h3.author
{
font-size: 100%
}
/*=============================================================================
Lists
=============================================================================*/
li
{
font-size: 10pt;
line-height: 1.3;
}
/* Unordered lists */
ul
{
text-align: left;
}
/* Ordered lists */
ol
{
text-align: left;
}
/*=============================================================================
Links
=============================================================================*/
a
{
text-decoration: none; /* no underline */
}
a:hover
{
text-decoration: underline;
}
/*=============================================================================
Spirit style navigation
=============================================================================*/
.spirit-nav
{
text-align: right;
}
.spirit-nav a
{
color: white;
padding-left: 0.5em;
}
.spirit-nav img
{
border-width: 0px;
}
/*=============================================================================
Table of contents
=============================================================================*/
/* Table of contents */
.toc
{
margin: 1pc 4% 0pc 4%;
padding: 0.1pc 1pc 0.1pc 1pc;
font-size: 80%;
line-height: 1.15;
}
.boost-toc
{
float: right;
padding: 0.5pc;
border: 1px solid gray;
}
/*=============================================================================
Tables
=============================================================================*/
.table-title,
div.table p.title
.informaltable table, .table table
{
margin-left: 4%;
padding-right: 0.5em;
padding-left: 0.5em;
}
.informaltable table,
.table table
{
width: 92%;
margin-left: 4%;
margin-right: 4%;
}
div.informaltable table,
div.table table
{
padding: 4px;
}
/* Table Cells */
div.informaltable table tr td,
div.table table tr td
{
padding: 0.5em;
text-align: left;
font-size: 9pt;
border: 1px solid gray;
border-collapse: collapse;
}
div.informaltable table tr th,
div.table table tr th
div.informaltable table tr td, div.table table tr td
{
padding: 0.5em 0.5em 0.5em 0.5em;
border: 1pt solid white;
font-size: 80%;
border: 1px solid gray;
}
/*=============================================================================
Blurbs
=============================================================================*/
div.note,
div.tip,
div.important,
div.caution,
div.warning,
p.blurb
div.informaltable table tr th, div.table table tr th
{
font-size: 9pt; /* A little bit smaller than the main text */
line-height: 1.2;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
p.blurb img
{
padding: 1pt;
border: 1px solid gray;
}
/*=============================================================================
Variable Lists
=============================================================================*/
/* Make the terms in definition lists bold */
div.variablelist dl dt,
span.term
span.highlight
{
font-weight: bold;
font-size: 10pt;
}
div.variablelist table tbody tr td
{
text-align: left;
vertical-align: top;
padding: 0em 2em 0em 0em;
font-size: 10pt;
margin: 0em 0em 0.5em 0em;
line-height: 1;
}
div.variablelist dl dt
{
margin-bottom: 0.2em;
}
div.variablelist dl dd
{
margin: 0em 0em 0.5em 2em;
font-size: 10pt;
}
div.variablelist table tbody tr td p,
div.variablelist dl dd p
{
margin: 0em 0em 0.5em 0em;
line-height: 1;
}
/*=============================================================================
Misc
=============================================================================*/
/* Title of books and articles in bibliographies */
span.title
{
font-style: italic;
}
span.underline
{
text-decoration: underline;
}
span.strikethrough
{
text-decoration: line-through;
}
/* Copyright, Legal Notice */
div div.legalnotice p
{
text-align: left
}
/*=============================================================================
Colors
=============================================================================*/
@media screen
{
/* Links */
a
{
color: #005a9c;
}
a:visited
{
color: #9c5a9c;
}
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
{
text-decoration: none; /* no underline */
color: #000000;
}
/* Syntax Highlighting */
.keyword { color: #0000AA; }
.identifier { color: #000000; }
.special { color: #707070; }
.preprocessor { color: #402080; }
.char { color: teal; }
.comment { color: #800000; }
.string { color: teal; }
.number { color: teal; }
.white_bkd { background-color: #FFFFFF; }
.dk_grey_bkd { background-color: #999999; }
/* Copyright, Legal Notice */
.copyright
{
color: #666666;
font-size: small;
}
div div.legalnotice p
{
color: #666666;
}
/* Program listing */
pre.synopsis
{
border: 1px solid #DCDCDC;
}
.programlisting,
.screen
{
border: 1px solid #DCDCDC;
}
td .programlisting,
td .screen
{
border: 0px solid #DCDCDC;
}
/* Blurbs */
div.note,
div.tip,
div.important,
div.caution,
div.warning,
p.blurb
{
border: 1px solid #DCDCDC;
}
/* Table of contents */
.toc
{
border: 1px solid #DCDCDC;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid #DCDCDC;
}
div.informaltable table tr th,
div.table table tr th
{
background-color: #F0F0F0;
border: 1px solid #DCDCDC;
}
/* Misc */
span.highlight
{
color: #00A000;
}
}
@media print
{
/* Links */
a
{
color: black;
}
a:visited
{
color: black;
}
.spirit-nav
{
display: none;
}
/* Program listing */
pre.synopsis
{
border: 1px solid gray;
}
.programlisting,
.screen
{
border: 1px solid gray;
}
td .programlisting,
td .screen
{
border: 0px solid #DCDCDC;
}
/* Table of contents */
.toc
{
border: 1px solid gray;
}
.informaltable table,
.table table
{
border: 1px solid gray;
border-collapse: collapse;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid gray;
}
div.informaltable table tr th,
div.table table tr th
{
border: 1px solid gray;
}
/* Misc */
span.highlight
{
font-weight: bold;
}
}
}

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -12,9 +9,9 @@
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td valign="top"><img alt="boost.png (6897 bytes)" 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="../../../../../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>
@@ -31,13 +28,15 @@
<div><div class="author"><h3 class="author">
<span class="firstname">David</span> <span class="surname">Abrahams</span>
</h3></div></div>
<div><p class="copyright">Copyright © 2002-2005 Joel
de Guzman, David Abrahams</p></div>
<div><p class="copyright">Copyright © 2002-2004 Joel de Guzman, David Abrahams</p></div>
<div><div class="legalnotice">
<a name="id376848"></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>)
<a name="id376569"></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>)
</p>
</div></div>
</div></div>
@@ -86,63 +85,45 @@
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="python.quickstart"></a>QuickStart</h2></div></div></div>
<p>
The Boost Python Library is a framework for interfacing Python and C++. It
allows you to quickly and seamlessly expose C++ classes functions and objects
to Python, and vice-versa, using no special tools -- just your C++ compiler.
It is designed to wrap C++ interfaces non-intrusively, so that you should not
have to change the C++ code at all in order to wrap it, making Boost.Python
ideal for exposing 3rd-party libraries to Python. The library's use of advanced
metaprogramming techniques simplifies its syntax for users, so that wrapping
code takes on the look of a kind of declarative interface definition language
(IDL).
</p>
The Boost Python Library is a framework for interfacing Python and
C++. It allows you to quickly and seamlessly expose C++ classes
functions and objects to Python, and vice-versa, using no special
tools -- just your C++ compiler. It is designed to wrap C++ interfaces
non-intrusively, so that you should not have to change the C++ code at
all in order to wrap it, making Boost.Python ideal for exposing
3rd-party libraries to Python. The library's use of advanced
metaprogramming techniques simplifies its syntax for users, so that
wrapping code takes on the look of a kind of declarative interface
definition language (IDL).</p>
<a name="quickstart.hello_world"></a><h2>
<a name="id447173"></a>
Hello World
</h2>
<a name="id376600"></a>Hello World</h2>
<p>
Following C/C++ tradition, let's start with the "hello, world". A
C++ Function:
</p>
<pre class="programlisting">
<span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">greet</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="string">"hello, world"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
Following C/C++ tradition, let's start with the "hello, world". A C++
Function:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">char</span><span class="keyword"> const</span><span class="special">*</span><span class="identifier"> greet</span><span class="special">()</span><span class="special">
{</span><span class="keyword">
return</span><span class="string"> "hello, world"</span><span class="special">;</span><span class="special">
}</span></tt></pre>
<p>
can be exposed to Python by writing a Boost.Python wrapper:
</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>
can be exposed to Python by writing a Boost.Python wrapper:</p>
<pre class="programlisting"><tt class="literal"><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">
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</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>
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</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></tt></pre>
<p>
That's it. We're done. We can now build this as a shared library. The resulting
DLL is now visible to Python. Here's a sample Python session:
</p>
<p>
</p>
<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>
<p>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="emphasis"><em><span class="bold"><b>Next stop... Building your Hello World module
from start to finish...</b></span></em></span>
</p></blockquote></div>
That's it. We're done. We can now build this as a shared library. The
resulting DLL is now visible to Python. Here's a sample Python session:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> import</span><span class="identifier"> hello</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> 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></tt></pre>
<div class="blockquote"><blockquote class="blockquote"><p><span class="emphasis"><em><span class="bold"><b>Next stop... Building your Hello World module from start to finish...</b></span></em></span></p></blockquote></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><small><p>Last revised: August 31, 2006 at 05:59:58 GMT</p></small></td>
<td align="left"><small><p>Last revised: October 12, 2004 at 03:11:11 GMT</p></small></td>
<td align="right"><small></small></td>
</tr></table>
<hr>

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -14,9 +11,9 @@
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td valign="top"><img alt="boost.png (6897 bytes)" 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="../../../../../../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>
@@ -30,178 +27,142 @@
<a name="python.embedding"></a>Embedding</h2></div></div></div>
<div class="toc"><dl><dt><span class="section"><a href="embedding.html#python.using_the_interpreter">Using the interpreter</a></span></dt></dl></div>
<p>
By now you should know how to use Boost.Python to call your C++ code from Python.
However, sometimes you may need to do the reverse: call Python code from the
C++-side. This requires you to <span class="emphasis"><em>embed</em></span> the Python interpreter
into your C++ program.
</p>
By now you should know how to use Boost.Python to call your C++ code from
Python. However, sometimes you may need to do the reverse: call Python code
from the C++-side. This requires you to <span class="emphasis"><em>embed</em></span> the Python interpreter
into your C++ program.</p>
<p>
Currently, Boost.Python does not directly support everything you'll need when
embedding. Therefore you'll need to use the <a href="http://www.python.org/doc/current/api/api.html" target="_top">Python/C
API</a> to fill in the gaps. However, Boost.Python already makes embedding
a lot easier and, in a future version, it may become unnecessary to touch the
Python/C API at all. So stay tuned... <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
</p>
Currently, Boost.Python does not directly support everything you'll need
when embedding. Therefore you'll need to use the
<a href="http://www.python.org/doc/current/api/api.html" target="_top">Python/C API</a> to fill in
the gaps. However, Boost.Python already makes embedding a lot easier and,
in a future version, it may become unnecessary to touch the Python/C API at
all. So stay tuned... <span class="inlinemediaobject"><img src="../images/smiley.png"></span></p>
<a name="embedding.building_embedded_programs"></a><h2>
<a name="id462650"></a>
Building embedded programs
</h2>
<a name="id460514"></a>Building embedded programs</h2>
<p>
To be able to use embedding in your programs, they have to be linked to both
Boost.Python's and Python's static link library.
</p>
To be able to use embedding in your programs, they have to be linked to
both Boost.Python's and Python's static link library.</p>
<p>
Boost.Python's static link library comes in two variants. Both are located
in Boost's <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>
Boost.Python's static link library comes in two variants. Both are located
in Boost's <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 static link 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>
Python's static link 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 <tt class="literal">/include</tt> subdirectory has to be added
to your include path.
</p>
Additionally, Python's <tt class="literal">/include</tt> subdirectory has to be added to your
include path.</p>
<p>
In a Jamfile, all the above boils down to:
</p>
<pre class="programlisting">projectroot c:\projects\embedded_program ; # location of the program
In a Jamfile, all the above boils down to:</p>
<pre class="programlisting"><tt class="literal"> projectroot c:\projects\embedded_program ; # location of the program
# bring in the rules for python
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
# bring in the rules for python
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
exe embedded_program # name of the executable
: #sources
embedded_program.cpp
: # requirements
&lt;find-library&gt;boost_python &lt;library-path&gt;c:\boost\libs\python
$(PYTHON_PROPERTIES)
&lt;library-path&gt;$(PYTHON_LIB_PATH)
&lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
</pre>
exe embedded_program # name of the executable
: #sources
embedded_program.cpp
: # requirements
&lt;find-library&gt;boost_python &lt;library-path&gt;c:\boost\libs\python
$(PYTHON_PROPERTIES)
&lt;library-path&gt;$(PYTHON_LIB_PATH)
&lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
</tt></pre>
<a name="embedding.getting_started"></a><h2>
<a name="id462747"></a>
Getting started
</h2>
<a name="id460605"></a>Getting started</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>
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 <tt class="literal">&lt;boost/python.hpp&gt;</tt><br><br>
#include <tt class="literal">&lt;boost/python.hpp&gt;</tt><p></p>
<p></p>
</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 <tt class="literal"><span class="underline">_main</span>_</tt>
module.<br><br>
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 <tt class="literal"><span class="underline">_main</span>_</tt> module.<p></p>
<p></p>
</li>
<li>
Call other Python C API routines to use the interpreter.<br><br>
Call other Python C API routines to use the interpreter.<p></p>
<p></p>
</li>
<li>
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
to stop the interpreter and release its resources.
</li>
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>() to stop the interpreter and release its resources.
</li>
</ol></div>
<p>
(Of course, there can be other C++ code between all of these steps.)
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="emphasis"><em><span class="bold"><b>Now that we can embed the interpreter in
our programs, lets see how to put it to use...</b></span></em></span>
</p></blockquote></div>
(Of course, there can be other C++ code between all of these steps.)</p>
<div class="blockquote"><blockquote class="blockquote"><p><span class="emphasis"><em><span class="bold"><b>Now that we can embed the interpreter in our programs, lets see how to put it to use...</b></span></em></span></p></blockquote></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
<p>
As you probably already know, objects in Python are reference-counted. Naturally,
the <tt class="literal">PyObject</tt>s of the Python/C API are also reference-counted.
There is a difference however. While the reference-counting is fully automatic
in Python, the Python/C API requires you to do it <a href="http://www.python.org/doc/current/api/refcounts.html" target="_top">by
hand</a>. This is messy and especially hard to get right in the presence
of C++ exceptions. Fortunately Boost.Python provides the <a href="../../../../v2/handle.html" target="_top">handle</a>
and <a href="../../../../v2/object.html" target="_top">object</a> class templates to
automate the process.
</p>
As you probably already know, objects in Python are reference-counted.
Naturally, the <tt class="literal">PyObject</tt>s of the Python/C API are also reference-counted.
There is a difference however. While the reference-counting is fully
automatic in Python, the Python/C API requires you to do it
<a href="http://www.python.org/doc/current/api/refcounts.html" target="_top">by hand</a>. This is
messy and especially hard to get right in the presence of C++ exceptions.
Fortunately Boost.Python provides the <a href="../../../../v2/handle.html" target="_top">handle</a> and
<a href="../../../../v2/object.html" target="_top">object</a> class templates to automate the process.</p>
<a name="using_the_interpreter.reference_counting_handles_and_objects"></a><h2>
<a name="id462914"></a>
Reference-counting handles and objects
</h2>
<a name="id460737"></a>Reference-counting handles and objects</h2>
<p>
There are two ways in which a function in the Python/C API can return a
<tt class="literal">PyObject*</tt>: as a <span class="emphasis"><em>borrowed reference</em></span>
or as a <span class="emphasis"><em>new reference</em></span>. Which of these a function uses,
is listed in that function's documentation. The two require slightely different
approaches to reference-counting but both can be 'handled' by Boost.Python.
</p>
There are two ways in which a function in the Python/C API can return a
<tt class="literal">PyObject*</tt>: as a <span class="emphasis"><em>borrowed reference</em></span> or as a <span class="emphasis"><em>new reference</em></span>. Which of
these a function uses, is listed in that function's documentation. The two
require slightely different approaches to reference-counting but both can
be 'handled' by Boost.Python.</p>
<p>
For a function returning a <span class="emphasis"><em>borrowed reference</em></span> we'll
have to tell the <tt class="literal">handle</tt> that the <tt class="literal">PyObject*</tt>
is borrowed with the aptly named <a href="../../../../v2/handle.html#borrowed-spec" target="_top">borrowed</a>
function. Two functions returning borrowed references are <a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a>
and <a href="http://www.python.org/doc/current/api/moduleObjects.html#l2h-594" target="_top">PyModule_GetDict</a>.
The former returns a reference to an already imported module, the latter
retrieves a module's namespace dictionary. Let's use them to retrieve the
namespace of the <tt class="literal"><span class="underline">_main</span>_</tt>
module:
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">main_module</span><span class="special">((</span>
<span class="identifier">handle</span><span class="special">&lt;&gt;(</span><span class="identifier">borrowed</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><span class="special">(</span><span class="string">"__main__"</span><span class="special">)))));</span>
For a function returning a <span class="emphasis"><em>borrowed reference</em></span> we'll have to tell the
<tt class="literal">handle</tt> that the <tt class="literal">PyObject*</tt> is borrowed with the aptly named
<a href="../../../../v2/handle.html#borrowed-spec" target="_top">borrowed</a> function. Two functions
returning borrowed references are <a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a> and <a href="http://www.python.org/doc/current/api/moduleObjects.html#l2h-594" target="_top">PyModule_GetDict</a>.
The former returns a reference to an already imported module, the latter
retrieves a module's namespace dictionary. Let's use them to retrieve the
namespace of the <tt class="literal"><span class="underline">_main</span>_</tt> module:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">object</span><span class="identifier"> main_module</span><span class="special">((</span><span class="identifier">
handle</span><span class="special">&lt;&gt;(</span><span class="identifier">borrowed</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><span class="special">(</span><span class="string">"__main__"</span><span class="special">)))));</span><span class="identifier">
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
</pre>
object</span><span class="identifier"> main_namespace</span><span class="special"> =</span><span class="identifier"> main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span></tt></pre>
<p>
For a function returning a <span class="emphasis"><em>new reference</em></span> we can just
create a <tt class="literal">handle</tt> out of the raw <tt class="literal">PyObject*</tt>
without wrapping it in a call to borrowed. One such function that returns
a new reference is <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
which we'll discuss in the next section.
</p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Handle is a class <span class="emphasis"><em>template</em></span>,
so why haven't we been using any template parameters?</b></span><br> <br>
<tt class="literal">handle</tt> has a single template parameter specifying the
type of the managed object. This type is <tt class="literal">PyObject</tt> 99%
of the time, so the parameter was defaulted to <tt class="literal">PyObject</tt>
for convenience. Therefore we can use the shorthand <tt class="literal">handle&lt;&gt;</tt>
instead of the longer, but equivalent, <tt class="literal">handle&lt;PyObject&gt;</tt>.
</p>
For a function returning a <span class="emphasis"><em>new reference</em></span> we can just create a <tt class="literal">handle</tt>
out of the raw <tt class="literal">PyObject*</tt> without wrapping it in a call to borrowed. One
such function that returns a new reference is <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a> which we'll
discuss in the next section.</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/note.png"></span><span class="bold"><b>Handle is a class <span class="emphasis"><em>template</em></span>, so why haven't we been using any template parameters?</b></span><p></p>
<p></p>
<tt class="literal">handle</tt> has a single template parameter specifying the type of the managed object. This type is <tt class="literal">PyObject</tt> 99% of the time, so the parameter was defaulted to <tt class="literal">PyObject</tt> for convenience. Therefore we can use the shorthand <tt class="literal">handle&lt;&gt;</tt> instead of the longer, but equivalent, <tt class="literal">handle&lt;PyObject&gt;</tt>.
</td></tr></tbody>
</table></div>
<a name="using_the_interpreter.running_python_code"></a><h2>
<a name="id463241"></a>
Running Python code
</h2>
<a name="id461039"></a>Running Python code</h2>
<p>
To run Python code from C++ there is a family of functions in the API starting
with the PyRun prefix. You can find the full list of these functions <a href="http://www.python.org/doc/current/api/veryhigh.html" target="_top">here</a>. They
all work similarly so we will look at only one of them, namely:
</p>
<pre class="programlisting">
<span class="identifier">PyObject</span><span class="special">*</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="keyword">char</span> <span class="special">*</span><span class="identifier">str</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">PyObject</span> <span class="special">*</span><span class="identifier">globals</span><span class="special">,</span> <span class="identifier">PyObject</span> <span class="special">*</span><span class="identifier">locals</span><span class="special">)</span>
</pre>
To run Python code from C++ there is a family of functions in the API
starting with the PyRun prefix. You can find the full list of these
functions <a href="http://www.python.org/doc/current/api/veryhigh.html" target="_top">here</a>. They
all work similarly so we will look at only one of them, namely:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">PyObject</span><span class="special">*</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="keyword">char</span><span class="special"> *</span><span class="identifier">str</span><span class="special">,</span><span class="keyword"> int</span><span class="identifier"> start</span><span class="special">,</span><span class="identifier"> PyObject</span><span class="special"> *</span><span class="identifier">globals</span><span class="special">,</span><span class="identifier"> PyObject</span><span class="special"> *</span><span class="identifier">locals</span><span class="special">)</span></tt></pre>
<p><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a> takes the code to execute as a null-terminated (C-style)
string in its <tt class="literal">str</tt> parameter. The function returns a new reference to a
Python object. Which object is returned depends on the <tt class="literal">start</tt> paramater.</p>
<p>
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
takes the code to execute as a null-terminated (C-style) string in its <tt class="literal">str</tt>
parameter. The function returns a new reference to a Python object. Which
object is returned depends on the <tt class="literal">start</tt> paramater.
</p>
<p>
The <tt class="literal">start</tt> parameter is the start symbol from the Python
grammar to use for interpreting the code. The possible values are:
</p>
The <tt class="literal">start</tt> parameter is the start symbol from the Python grammar to use
for interpreting the code. The possible values are:</p>
<div class="informaltable">
<h4>
<a name="id463420"></a>
<span class="table-title">Start symbols</span>
</h4>
<a name="id461201"></a><span class="table-title">Start symbols</span>
</h4>
<table class="table">
<colgroup>
<col>
@@ -209,211 +170,168 @@ exe embedded_program # name of the executable
</colgroup>
<thead><tr>
<th><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a></th>
<th>for
interpreting isolated expressions</th>
<th>for interpreting isolated expressions</th>
</tr></thead>
<tbody>
<tr>
<td><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a></td>
<td>for
interpreting sequences of statements</td>
<td>for interpreting sequences of statements</td>
</tr>
<tr>
<td><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-60" target="_top">Py_single_input</a></td>
<td>for
interpreting a single statement</td>
<td>for interpreting a single statement</td>
</tr>
</tbody>
</table>
</div>
<p>
When using <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>,
the input string must contain a single expression and its result is returned.
When using <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>,
the string can contain an abitrary number of statements and None is returned.
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-60" target="_top">Py_single_input</a>
works in the same way as <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>
but only accepts a single statement.
</p>
When using <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>, the input string must contain a single expression
and its result is returned. When using <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>, the string can
contain an abitrary number of statements and None is returned.
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-60" target="_top">Py_single_input</a> works in the same way as <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a> but only accepts a
single statement.</p>
<p>
Lastly, 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 <tt class="literal"><span class="underline">_main</span>_</tt>
module for both parameters.
</p>
Lastly, 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
<tt class="literal"><span class="underline">_main</span>_</tt> module for both parameters.</p>
<p>
We have already seen how to get the <tt class="literal"><span class="underline">_main</span>_</tt>
module's namespace so let's run some Python code in it:
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">main_module</span><span class="special">((</span>
<span class="identifier">handle</span><span class="special">&lt;&gt;(</span><span class="identifier">borrowed</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><span class="special">(</span><span class="string">"__main__"</span><span class="special">)))));</span>
We have already seen how to get the <tt class="literal"><span class="underline">_main</span>_</tt> module's namespace so let's
run some Python code in it:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">object</span><span class="identifier"> main_module</span><span class="special">((</span><span class="identifier">
handle</span><span class="special">&lt;&gt;(</span><span class="identifier">borrowed</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><span class="special">(</span><span class="string">"__main__"</span><span class="special">)))));</span><span class="identifier">
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
object</span><span class="identifier"> main_namespace</span><span class="special"> =</span><span class="identifier"> main_module</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="identifier">
<span class="identifier">handle</span><span class="special">&lt;&gt;</span> <span class="identifier">ignored</span><span class="special">((</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
handle</span><span class="special">&lt;&gt;</span><span class="identifier"> ignored</span><span class="special">((</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="string">
<span class="string">"hello = file('hello.txt', 'w')\n"</span>
<span class="string">"hello.write('Hello world!')\n"</span>
<span class="string">"hello.close()"</span>
"hello = file('hello.txt', 'w')\n"</span><span class="string">
"hello.write('Hello world!')\n"</span><span class="string">
"hello.close()"</span><span class="special">
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span>
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">())</span>
<span class="special">));</span>
</pre>
,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a><span class="special">
,</span><span class="identifier"> main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span><span class="special">
,</span><span class="identifier"> main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">())</span><span class="special">
));</span></tt></pre>
<p>
Because the Python/C API doesn't know anything about <tt class="literal">object</tt>s,
we used the object's <tt class="literal">ptr</tt> member function to retrieve the
<tt class="literal">PyObject*</tt>.
</p>
Because the Python/C API doesn't know anything about <tt class="literal">object</tt>s, we used
the object's <tt class="literal">ptr</tt> member function to retrieve the <tt class="literal">PyObject*</tt>.</p>
<p>
This should create a file called 'hello.txt' in the current directory containing
a phrase that is well-known in programming circles.
</p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Note</b></span> that we wrap
the return value of <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
in a (nameless) <tt class="literal">handle</tt> even though we are not interested
in it. If we didn't do this, the the returned object would be kept alive
unnecessarily. Unless you want to be a Dr. Frankenstein, always wrap <tt class="literal">PyObject*</tt>s
in <tt class="literal">handle</tt>s.
</p>
This should create a file called 'hello.txt' in the current directory
containing a phrase that is well-known in programming circles.</p>
<p><span class="inlinemediaobject"><img src="../images/note.png"></span><span class="bold"><b>Note</b></span> that we wrap the return value of <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a> in a
(nameless) <tt class="literal">handle</tt> even though we are not interested in it. If we didn't
do this, the the returned object would be kept alive unnecessarily. Unless
you want to be a Dr. Frankenstein, always wrap <tt class="literal">PyObject*</tt>s in <tt class="literal">handle</tt>s.</p>
<a name="using_the_interpreter.beyond_handles"></a><h2>
<a name="id463926"></a>
Beyond handles
</h2>
<a name="id461639"></a>Beyond handles</h2>
<p>
It's nice that <tt class="literal">handle</tt> manages the reference counting details
for us, but other than that it doesn't do much. Often we'd like to have a
more useful 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 <tt class="literal">object</tt> class and it's 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">
<span class="identifier">object</span> <span class="identifier">main_module</span><span class="special">((</span>
<span class="identifier">handle</span><span class="special">&lt;&gt;(</span><span class="identifier">borrowed</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><span class="special">(</span><span class="string">"__main__"</span><span class="special">)))));</span>
It's nice that <tt class="literal">handle</tt> manages the reference counting details for us, but
other than that it doesn't do much. Often we'd like to have a more useful
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 <tt class="literal">object</tt> class and it's 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"><tt class="literal"><span class="identifier">object</span><span class="identifier"> main_module</span><span class="special">((</span><span class="identifier">
handle</span><span class="special">&lt;&gt;(</span><span class="identifier">borrowed</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><span class="special">(</span><span class="string">"__main__"</span><span class="special">)))));</span><span class="identifier">
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
object</span><span class="identifier"> main_namespace</span><span class="special"> =</span><span class="identifier"> main_module</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="identifier">
<span class="identifier">handle</span><span class="special">&lt;&gt;</span> <span class="identifier">ignored</span><span class="special">((</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
handle</span><span class="special">&lt;&gt;</span><span class="identifier"> ignored</span><span class="special">((</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="string">
<span class="string">"result = 5 ** 2"</span>
"result = 5 ** 2"</span><span class="special">
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span>
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">())</span>
<span class="special">));</span>
,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a><span class="special">
,</span><span class="identifier"> main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span><span class="special">
,</span><span class="identifier"> main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">())</span><span class="special">
));</span><span class="keyword">
<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>
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></tt></pre>
<p>
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 let <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
return the result directly with <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>:
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">result</span><span class="special">((</span><span class="identifier">handle</span><span class="special">&lt;&gt;(</span>
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="string">"5 ** 2"</span>
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span>
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))</span>
<span class="special">));</span>
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 let
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a> return the result directly with <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">object</span><span class="identifier"> result</span><span class="special">((</span><span class="identifier">handle</span><span class="special">&lt;&gt;(</span>
    <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">
,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a><span class="special">
,</span><span class="identifier"> main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span><span class="special">
,</span><span class="identifier"> main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))</span><span class="special">
));</span><span class="keyword">
<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>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Note</b></span> that <tt class="literal">object</tt>'s
member function to return the wrapped <tt class="literal">PyObject*</tt> is called
<tt class="literal">ptr</tt> instead of <tt class="literal">get</tt>. This makes sense
if you take into account the different functions that <tt class="literal">object</tt>
and <tt class="literal">handle</tt> perform.
</p>
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></tt></pre>
<p><span class="inlinemediaobject"><img src="../images/note.png"></span><span class="bold"><b>Note</b></span> that <tt class="literal">object</tt>'s member function to return the wrapped
<tt class="literal">PyObject*</tt> is called <tt class="literal">ptr</tt> instead of <tt class="literal">get</tt>. This makes sense if you
take into account the different functions that <tt class="literal">object</tt> and <tt class="literal">handle</tt>
perform.</p>
<a name="using_the_interpreter.exception_handling"></a><h2>
<a name="id464549"></a>
Exception handling
</h2>
<a name="id462209"></a>Exception handling</h2>
<p>
If an exception occurs in the execution of some Python code, the <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
function returns a null pointer. Constructing a <tt class="literal">handle</tt>
out of this null pointer throws <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>,
so basically, the Python exception is automatically translated into a C++
exception when using <tt class="literal">handle</tt>:
</p>
<pre class="programlisting">
<span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">object</span> <span class="identifier">result</span><span class="special">((</span><span class="identifier">handle</span><span class="special">&lt;&gt;(</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
<span class="string">"5/0"</span>
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span>
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))</span>
<span class="special">));</span>
If an exception occurs in the execution of some Python code, the <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
function returns a null pointer. Constructing a <tt class="literal">handle</tt> out of this null
pointer throws <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>,
so basically, the Python exception is automatically translated into a
C++ exception when using <tt class="literal">handle</tt>:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">try</span><span class="special">
{</span><span class="identifier">
object</span><span class="identifier"> result</span><span class="special">((</span><span class="identifier">handle</span><span class="special">&lt;&gt;(</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="string">
"5/0"</span><span class="special">
,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a><span class="special">
,</span><span class="identifier"> main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span><span class="special">
,</span><span class="identifier"> main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))</span><span class="special">
));</span><span class="comment">
<span class="comment">// execution will never get here:
</span> <span class="keyword">int</span> <span class="identifier">five_divided_by_zero</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>
<span class="special">}</span>
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// handle the exception in some way
</span><span class="special">}</span>
</pre>
// execution will never get here:
</span><span class="keyword"> int</span><span class="identifier"> five_divided_by_zero</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><span class="special">
}</span><span class="keyword">
catch</span><span class="special">(</span><span class="identifier">error_already_set</span><span class="special">)</span><span class="special">
{</span><span class="comment">
// handle the exception in some way
</span><span class="special">}</span></tt></pre>
<p>
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/C API in your catch-statement. This
can be as simple as calling <a href="http://www.python.org/doc/api/exceptionHandling.html#l2h-70" target="_top">PyErr_Print()</a>
to print the exception's traceback to the console, or comparing the type
of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
exceptions</a>:
</p>
<pre class="programlisting">
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">PyErr_ExceptionMatches</span><span class="special">(</span><span class="identifier">PyExc_ZeroDivisionError</span><span class="special">))</span>
<span class="special">{</span>
<span class="comment">// handle ZeroDivisionError specially
</span> <span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="comment">// print all other errors to stderr
</span> <span class="identifier">PyErr_Print</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
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/C API in your catch-statement. This can be as simple as calling
<a href="http://www.python.org/doc/api/exceptionHandling.html#l2h-70" target="_top">PyErr_Print()</a> to
print the exception's traceback to the console, or comparing the type of the
exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html%20standard" target="_top">exceptions</a>:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span><span class="special">)</span><span class="special">
{</span><span class="keyword">
if</span><span class="special"> (</span><span class="identifier">PyErr_ExceptionMatches</span><span class="special">(</span><span class="identifier">PyExc_ZeroDivisionError</span><span class="special">))</span><span class="special">
{</span><span class="comment">
// handle ZeroDivisionError specially
</span><span class="special"> }</span><span class="keyword">
else</span><span class="special">
{</span><span class="comment">
// print all other errors to stderr
</span><span class="identifier"> PyErr_Print</span><span class="special">();</span><span class="special">
}</span><span class="special">
}</span></tt></pre>
<p>
(To retrieve even more information from the exception you can use some of
the other exception handling functions listed <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">here</a>.)
</p>
(To retrieve even more information from the exception you can use some of the other
exception handling functions listed <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">here</a>.)</p>
<p>
If you'd rather not have <tt class="literal">handle</tt> throw a C++ exception
when it is constructed, you can use the <a href="../../../../v2/handle.html#allow_null-spec" target="_top">allow_null</a>
function in the same way you'd use borrowed:
</p>
<pre class="programlisting">
<span class="identifier">handle</span><span class="special">&lt;&gt;</span> <span class="identifier">result</span><span class="special">((</span><span class="identifier">allow_null</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
<span class="string">"5/0"</span>
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span>
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))));</span>
If you'd rather not have <tt class="literal">handle</tt> throw a C++ exception when it is constructed, you
can use the <a href="../../../../v2/handle.html#allow_null-spec" target="_top">allow_null</a> function in the same
way you'd use borrowed:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">handle</span><span class="special">&lt;&gt;</span><span class="identifier"> result</span><span class="special">((</span><span class="identifier">allow_null</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="string">
"5/0"</span><span class="special">
,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a><span class="special">
,</span><span class="identifier"> main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span><span class="special">
,</span><span class="identifier"> main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))));</span><span class="keyword">
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">result</span><span class="special">)</span>
<span class="comment">// Python exception occurred
</span><span class="keyword">else</span>
<span class="comment">// everything went okay, it's safe to use the result
</span></pre>
if</span><span class="special"> (!</span><span class="identifier">result</span><span class="special">)</span><span class="comment">
// Python exception occurred
</span><span class="keyword">else</span><span class="comment">
// everything went okay, it's safe to use the result
</span></tt></pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright © 2002-2005 Joel
de Guzman, David Abrahams</small></td>
<td align="right"><small>Copyright © 2002-2004 Joel de Guzman, David Abrahams</small></td>
</tr></table>
<hr>
<div class="spirit-nav">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -14,9 +11,9 @@
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td valign="top"><img alt="boost.png (6897 bytes)" 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="../../../../../../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>
@@ -29,31 +26,25 @@
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="python.exception"></a> Exception Translation</h2></div></div></div>
<p>
All C++ exceptions must be caught at the boundary with Python code. This boundary
is the point where C++ meets Python. Boost.Python provides a default exception
handler that translates selected standard exceptions, then gives up:
</p>
<pre class="programlisting">
<span class="keyword">raise</span> <span class="identifier">RuntimeError</span><span class="special">,</span> <span class="string">'unidentifiable C++ Exception'</span>
</pre>
All C++ exceptions must be caught at the boundary with Python code. This
boundary is the point where C++ meets Python. Boost.Python provides a
default exception handler that translates selected standard exceptions,
then gives up:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">raise</span><span class="identifier"> RuntimeError</span><span class="special">,</span><span class="char"> 'unidentifiable C++ Exception'</span></tt></pre>
<p>
Users may provide custom translation. Here's an example:
</p>
<pre class="programlisting">
<span class="identifier">struct</span> <span class="identifier">PodBayDoorException</span><span class="special">;</span>
<span class="identifier">void</span> <span class="identifier">translator</span><span class="special">(</span><span class="identifier">PodBayDoorException</span> <span class="identifier">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">PyErr_SetString</span><span class="special">(</span><span class="identifier">PyExc_UserWarning</span><span class="special">,</span> <span class="string">"I'm sorry Dave..."</span><span class="special">);</span>
<span class="special">}</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">kubrick</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">register_exception_translator</span><span class="special">&lt;</span>
<span class="identifier">PodBayDoorException</span><span class="special">&gt;(</span><span class="identifier">translator</span><span class="special">);</span>
<span class="special">...</span>
</pre>
Users may provide custom translation. Here's an example:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> PodBayDoorException</span><span class="special">;</span><span class="keyword">
void</span><span class="identifier"> translator</span><span class="special">(</span><span class="identifier">PodBayDoorException</span><span class="keyword"> const</span><span class="special">&amp;</span><span class="identifier"> x</span><span class="special">)</span><span class="special"> {</span><span class="identifier">
PyErr_SetString</span><span class="special">(</span><span class="identifier">PyExc_UserWarning</span><span class="special">,</span><span class="string"> "I'm sorry Dave..."</span><span class="special">);</span><span class="special">
}</span><span class="identifier">
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">kubrick</span><span class="special">)</span><span class="special"> {</span><span class="identifier">
register_exception_translator</span><span class="special">&lt;</span><span class="identifier">
PodBayDoorException</span><span class="special">&gt;(</span><span class="identifier">translator</span><span class="special">);</span><span class="special">
...</span></tt></pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright © 2002-2005 Joel
de Guzman, David Abrahams</small></td>
<td align="right"><small>Copyright © 2002-2004 Joel de Guzman, David Abrahams</small></td>
</tr></table>
<hr>
<div class="spirit-nav">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -14,9 +11,9 @@
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td valign="top"><img alt="boost.png (6897 bytes)" 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="../../../../../../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>
@@ -38,568 +35,437 @@
<dt><span class="section"><a href="exposing.html#python.class_operators_special_functions">Class Operators/Special Functions</a></span></dt>
</dl></div>
<p>
Now let's expose a C++ class to Python.
</p>
Now let's expose a C++ class to Python.</p>
<p>
Consider a C++ class/struct that we want to expose to Python:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">World</span>
<span class="special">{</span>
<span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">greet</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">;</span>
<span class="special">};</span>
</pre>
Consider a C++ class/struct that we want to expose to Python:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> World</span><span class="special">
{</span><span class="keyword">
void</span><span class="identifier"> set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="identifier"> msg</span><span class="special">)</span><span class="special"> {</span><span class="keyword"> this</span><span class="special">-&gt;</span><span class="identifier">msg</span><span class="special"> =</span><span class="identifier"> msg</span><span class="special">;</span><span class="special"> }</span><span class="identifier">
std</span><span class="special">::</span><span class="identifier">string</span><span class="identifier"> greet</span><span class="special">()</span><span class="special"> {</span><span class="keyword"> return</span><span class="identifier"> msg</span><span class="special">;</span><span class="special"> }</span><span class="identifier">
std</span><span class="special">::</span><span class="identifier">string</span><span class="identifier"> msg</span><span class="special">;</span><span class="special">
};</span></tt></pre>
<p>
We can expose this to Python by writing a corresponding Boost.Python C++ Wrapper:
</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>
We can expose this to Python by writing a corresponding Boost.Python
C++ Wrapper:</p>
<pre class="programlisting"><tt class="literal"><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">
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">)</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="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span>
<span class="special">;</span>
<span class="special">}</span>
</pre>
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span><span class="special">
{</span><span class="identifier">
class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">)</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="special"> &amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span><span class="special">
;</span><span class="special">
}</span></tt></pre>
<p>
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>
</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="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="string">'howdy'</span><span class="special">)</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
<span class="string">'howdy'</span>
</pre>
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>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> import</span><span class="identifier"> hello</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> planet</span><span class="special"> =</span><span class="identifier"> hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> planet</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="char">'howdy'</span><span class="special">)</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> planet</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span><span class="char">
'howdy'</span></tt></pre>
<div class="section" lang="en">
<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 <tt class="literal">World</tt>
is declared as a plain struct, it has an implicit default constructor. Boost.Python
exposes the default constructor by default, which is why we were able to
write
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
</pre>
Our previous example didn't have any explicit constructors.
Since <tt class="literal">World</tt> is declared as a plain struct, it has an implicit default
constructor. Boost.Python exposes the default constructor by default,
which is why we were able to write</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> planet</span><span class="special"> =</span><span class="identifier"> hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span></tt></pre>
<p>
We may wish to wrap a class with a non-default constructor. Let us build
on our previous example:
</p>
We may wish to wrap a class with a non-default constructor. Let us
build on our previous example:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> World</span><span class="special">
{</span><span class="identifier">
World</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="identifier"> msg</span><span class="special">):</span><span class="identifier"> msg</span><span class="special">(</span><span class="identifier">msg</span><span class="special">)</span><span class="special"> {}</span><span class="comment"> // added constructor
</span><span class="keyword"> void</span><span class="identifier"> set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="identifier"> msg</span><span class="special">)</span><span class="special"> {</span><span class="keyword"> this</span><span class="special">-&gt;</span><span class="identifier">msg</span><span class="special"> =</span><span class="identifier"> msg</span><span class="special">;</span><span class="special"> }</span><span class="identifier">
std</span><span class="special">::</span><span class="identifier">string</span><span class="identifier"> greet</span><span class="special">()</span><span class="special"> {</span><span class="keyword"> return</span><span class="identifier"> msg</span><span class="special">;</span><span class="special"> }</span><span class="identifier">
std</span><span class="special">::</span><span class="identifier">string</span><span class="identifier"> msg</span><span class="special">;</span><span class="special">
};</span></tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">World</span>
<span class="special">{</span>
<span class="identifier">World</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">):</span> <span class="identifier">msg</span><span class="special">(</span><span class="identifier">msg</span><span class="special">)</span> <span class="special">{}</span> <span class="comment">// added constructor
</span> <span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">greet</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
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 <tt class="literal">class_&lt;World&gt;</tt> about the constructor
we want to expose instead.
</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>
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 <tt class="literal">class_&lt;World&gt;</tt> about the constructor we want to
expose instead.</p>
<pre class="programlisting"><tt class="literal"><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">
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</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="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span>
<span class="special">;</span>
<span class="special">}</span>
</pre>
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span><span class="special">
{</span><span class="identifier">
class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">,</span><span class="identifier"> init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</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="special"> &amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span><span class="special">
;</span><span class="special">
}</span></tt></pre>
<p><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>
<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>
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"><tt class="literal"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">,</span><span class="identifier"> init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span><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">double</span><span class="special">,</span><span class="keyword"> double</span><span class="special">&gt;())</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="special"> &amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span><span class="special">
;</span></tt></pre>
<p>
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">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span>
<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">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;())</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="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span>
<span class="special">;</span>
</pre>
On the other hand, if we do not wish to expose any constructors at
all, we may use <tt class="literal">no_init</tt> instead:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
On the other hand, if we do not wish to expose any constructors at all, we
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 <tt class="literal"><span class="underline">_init</span>_</tt>
method which always raises a Python RuntimeError exception.
</p>
This actually adds an <tt class="literal"><span class="underline">_init</span>_</tt> method which always raises a
Python RuntimeError exception.</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.class_data_members"></a>Class Data Members</h3></div></div></div>
<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"><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>
<span class="special">{</span>
<span class="identifier">Var</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">name</span><span class="special">(</span><span class="identifier">name</span><span class="special">),</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">{}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="identifier">name</span><span class="special">;</span>
<span class="keyword">float</span> <span class="identifier">value</span><span class="special">;</span>
<span class="special">};</span>
</pre>
Data members may also be exposed to Python so that they can be
accessed as attributes of the corresponding Python class. Each data
member that we wish to be exposed may be regarded as <span class="bold"><b>read-only</b></span> or
<span class="bold"><b>read-write</b></span>. Consider this class <tt class="literal">Var</tt>:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> Var</span><span class="special">
{</span><span class="identifier">
Var</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="identifier"> name</span><span class="special">)</span><span class="special"> :</span><span class="identifier"> name</span><span class="special">(</span><span class="identifier">name</span><span class="special">),</span><span class="identifier"> value</span><span class="special">()</span><span class="special"> {}</span><span class="identifier">
std</span><span class="special">::</span><span class="identifier">string</span><span class="keyword"> const</span><span class="identifier"> name</span><span class="special">;</span><span class="keyword">
float</span><span class="identifier"> value</span><span class="special">;</span><span class="special">
};</span></tt></pre>
<p>
Our C++ <tt class="literal">Var</tt> class and its data members can be exposed
to Python:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Var</span><span class="special">&gt;(</span><span class="string">"Var"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span>
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"name"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">name</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def_readwrite</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">value</span><span class="special">);</span>
</pre>
Our C++ <tt class="literal">Var</tt> class and its data members can be exposed to Python:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Var</span><span class="special">&gt;(</span><span class="string">"Var"</span><span class="special">,</span><span class="identifier"> init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span><span class="special">
.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"name"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">name</span><span class="special">)</span><span class="special">
.</span><span class="identifier">def_readwrite</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">value</span><span class="special">);</span></tt></pre>
<p>
Then, in Python, assuming we have placed our Var class inside the namespace
hello as we did before:
</p>
Then, in Python, assuming we have placed our Var class inside the namespace
hello as we did before:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> x</span><span class="special"> =</span><span class="identifier"> hello</span><span class="special">.</span><span class="identifier">Var</span><span class="special">(</span><span class="char">'pi'</span><span class="special">)</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">value</span><span class="special"> =</span><span class="number"> 3.14</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> print</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">name</span><span class="special">,</span><span class="char"> 'is around'</span><span class="special">,</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">value</span><span class="identifier">
pi</span><span class="identifier"> is</span><span class="identifier"> around</span><span class="number"> 3.14</span></tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">Var</span><span class="special">(</span><span class="string">'pi'</span><span class="special">)</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span><span class="special">,</span> <span class="string">'is around'</span><span class="special">,</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span>
<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 <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
</span><span class="identifier">Traceback</span> <span class="special">(</span><span class="identifier">most</span> <span class="identifier">recent</span> <span class="identifier">call</span> <span class="identifier">last</span><span class="special">):</span>
<span class="identifier">File</span> <span class="string">"&lt;stdin&gt;"</span><span class="special">,</span> <span class="identifier">line</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">in</span> #
<span class="identifier">AttributeError</span><span class="special">:</span> <span class="identifier">can</span>#<span class="identifier">t</span> <span class="identifier">set</span> <span class="identifier">attribute</span>
</pre>
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"><tt class="literal"> &gt;&gt;&gt; x.name = 'e' # can't change name
Traceback (most recent call last):
File "&lt;stdin&gt;", line 1, in ?
AttributeError: can't set attribute
</tt></pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.class_properties"></a>Class Properties</h3></div></div></div>
<p>
In C++, classes with public data members are usually frowned upon. Well designed
classes that take advantage of encapsulation hide the class' data members.
The only way to access the class' data is through access (getter/setter)
functions. Access functions expose class properties. Here's an example:
</p>
In C++, classes with public data members are usually frowned
upon. Well designed classes that take advantage of encapsulation hide
the class' data members. The only way to access the class' data is
through access (getter/setter) functions. Access functions expose class
properties. Here's an example:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> Num</span><span class="special">
{</span><span class="identifier">
Num</span><span class="special">();</span><span class="keyword">
float</span><span class="identifier"> get</span><span class="special">()</span><span class="keyword"> const</span><span class="special">;</span><span class="keyword">
void</span><span class="identifier"> set</span><span class="special">(</span><span class="keyword">float</span><span class="identifier"> value</span><span class="special">);</span><span class="special">
...</span><span class="special">
};</span></tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Num</span>
<span class="special">{</span>
<span class="identifier">Num</span><span class="special">();</span>
<span class="keyword">float</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">value</span><span class="special">);</span>
<span class="special">...</span>
<span class="special">};</span>
</pre>
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
<tt class="literal">Num</tt> class using Boost.Python:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Num</span><span class="special">&gt;(</span><span class="string">"Num"</span><span class="special">)</span><span class="special">
.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span><span class="special">
.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">set</span><span class="special">);</span></tt></pre>
<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 <tt class="literal">Num</tt>
class using Boost.Python:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Num</span><span class="special">&gt;(</span><span class="string">"Num"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">set</span><span class="special">);</span>
</pre>
And at last, in Python:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> x</span><span class="special"> =</span><span class="identifier"> Num</span><span class="special">()</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">value</span><span class="special"> =</span><span class="number"> 3.14</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">value</span><span class="special">,</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">rovalue</span><span class="special">
(</span><span class="number">3.14</span><span class="special">,</span><span class="number"> 3.14</span><span class="special">)</span><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="identifier"> error</span><span class="special">!</span></tt></pre>
<p>
And at last, in Python:
</p>
<p>
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Num</span><span class="special">()</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span><span class="special">,</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span>
<span class="special">(</span><span class="number">3.14</span><span class="special">,</span> <span class="number">3.14</span><span class="special">)</span>
<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 <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>
</p>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
</pre>
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>
<pre class="programlisting"><tt class="literal"><span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span></tt></pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.inheritance"></a>Inheritance</h3></div></div></div>
<p>
In the previous examples, we dealt with classes that are not polymorphic.
This is not often the case. Much of the time, we will be wrapping polymorphic
classes and class hierarchies related by inheritance. We will often have
to write Boost.Python wrappers for classes that are derived from abstract
base classes.
</p>
In the previous examples, we dealt with classes that are not polymorphic.
This is not often the case. Much of the time, we will be wrapping
polymorphic classes and class hierarchies related by inheritance. We will
often have to write Boost.Python wrappers for classes that are derived from
abstract base classes.</p>
<p>
Consider this trivial inheritance structure:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span> <span class="special">{</span> <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">();</span> <span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">Derived</span> <span class="special">:</span> <span class="identifier">Base</span> <span class="special">{};</span>
</pre>
Consider this trivial inheritance structure:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> Base</span><span class="special"> {</span><span class="keyword"> virtual</span><span class="special"> ~</span><span class="identifier">Base</span><span class="special">();</span><span class="special"> };</span><span class="keyword">
struct</span><span class="identifier"> Derived</span><span class="special"> :</span><span class="identifier"> Base</span><span class="special"> {};</span></tt></pre>
<p>
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">
<span class="keyword">void</span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">Base</span><span class="special">*);</span>
<span class="keyword">void</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">Derived</span><span class="special">*);</span>
<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>
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"><tt class="literal"><span class="keyword">void</span><span class="identifier"> b</span><span class="special">(</span><span class="identifier">Base</span><span class="special">*);</span><span class="keyword">
void</span><span class="identifier"> d</span><span class="special">(</span><span class="identifier">Derived</span><span class="special">*);</span><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></tt></pre>
<p>
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>
<span class="comment">/*...*/</span>
<span class="special">;</span>
</pre>
We've seen how we can wrap the base class <tt class="literal">Base</tt>:</p>
<pre class="programlisting"><tt class="literal"><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><span class="comment">
/*...*/</span><span class="special">
;</span></tt></pre>
<p>
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>
<span class="comment">/*...*/</span>
<span class="special">;</span>
</pre>
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"><tt class="literal"><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><span class="comment">
/*...*/</span><span class="special">
;</span></tt></pre>
<p>
Doing so, we get some things for free:
</p>
Doing so, we get some things for free:</p>
<div class="orderedlist"><ol type="1">
<li>
Derived automatically inherits all of Base's Python methods (wrapped C++
member functions)
</li>
Derived automatically inherits all of Base's Python methods
(wrapped C++ member functions)
</li>
<li>
<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
<tt class="literal">Base</tt> can be passed where a pointer or reference to
<tt class="literal">Derived</tt> is expected.
</li>
<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 <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 <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>
<span class="identifier">def</span><span class="special">(</span><span class="string">"d"</span><span class="special">,</span> <span class="identifier">d</span><span class="special">);</span>
<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>
Now, we shall 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"><tt class="literal"><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><span class="identifier">
def</span><span class="special">(</span><span class="string">"d"</span><span class="special">,</span><span class="identifier"> d</span><span class="special">);</span><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></tt></pre>
<p>
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 shall see more of Boost.Python <a href="functions.html#python.call_policies" title="Call Policies">call
policies</a> later.
</p>
<pre class="programlisting">
<span class="comment">// Tell Python to take ownership of factory's result
</span><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>
<span class="identifier">return_value_policy</span><span class="special">&lt;</span><span class="identifier">manage_new_object</span><span class="special">&gt;());</span>
</pre>
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 shall see more of
Boost.Python <a href="functions.html#python.call_policies" title="Call Policies">call policies</a> later.</p>
<pre class="programlisting"><tt class="literal"><span class="comment">// Tell Python to take ownership of factory's result
</span><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><span class="identifier">
return_value_policy</span><span class="special">&lt;</span><span class="identifier">manage_new_object</span><span class="special">&gt;());</span></tt></pre>
</div>
<div class="section" lang="en">
<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
through virtual functions. Continuing our example, let us add a virtual function
to our <tt class="literal">Base</tt> class:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span>
<span class="special">{</span>
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">()</span> <span class="special">{}</span>
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="special">};</span>
</pre>
In this section, we shall learn how to make functions behave polymorphically
through virtual functions. Continuing our example, let us add a virtual function
to our <tt class="literal">Base</tt> class:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> Base</span><span class="special">
{</span><span class="keyword">
virtual</span><span class="special"> ~</span><span class="identifier">Base</span><span class="special">()</span><span class="special"> {}</span><span class="keyword">
virtual</span><span class="keyword"> int</span><span class="identifier"> f</span><span class="special">()</span><span class="special"> =</span><span class="number"> 0</span><span class="special">;</span><span class="special">
};</span></tt></pre>
<p>
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 <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"><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 <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>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">return</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="special">}</span>
<span class="special">};</span>
</pre>
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
<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"><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 <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>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> BaseWrap</span><span class="special"> :</span><span class="identifier"> Base</span><span class="special">,</span><span class="identifier"> wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span><span class="special">
{</span><span class="keyword">
int</span><span class="identifier"> f</span><span class="special">()</span><span class="special">
{</span><span class="keyword">
return</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="special">
}</span><span class="special">
};</span></tt></pre>
<p>
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>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to write <tt class="computeroutput"><span class="identifier">f</span></tt> as:<br> <br> <tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special">&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>
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="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/alert.png"></span> MSVC6/7 Workaround<p></p>
<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>
<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>.</td></tr></tbody>
</table></div>
<p>
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>
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 <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>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">pure_virtual</span><span class="special">(&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">))</span>
<span class="special">;</span>
</pre>
<p>
<tt class="computeroutput"><span class="identifier">pure_virtual</span></tt> signals Boost.Python
that the function <tt class="computeroutput"><span class="identifier">f</span></tt> is a
pure virtual function.
</p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>member function and methods</b></span><br>
<br> Python, like many object oriented languages uses the term <span class="bold"><b>methods</b></span>. Methods correspond roughly to C++'s <span class="bold"><b>member functions</b></span>
</p>
Finally, exposing <tt class="computeroutput"><span class="identifier">Base</span></tt>:</p>
<pre class="programlisting"><tt class="literal"><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><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> pure_virtual</span><span class="special">(&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">))</span><span class="special">
;</span></tt></pre>
<p><tt class="computeroutput"><span class="identifier">pure_virtual</span></tt> signals Boost.Python that the function <tt class="computeroutput"><span class="identifier">f</span></tt> is a pure virtual
function.</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/note.png"></span><span class="bold"><b>member function and methods</b></span><p></p>
<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>
</td></tr></tbody>
</table></div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.virtual_functions_with_default_implementations"></a>Virtual Functions with Default Implementations</h3></div></div></div>
<p>
We've seen in the previous section how classes with pure virtual functions
are wrapped using Boost.Python's <a href="../../../../v2/wrapper.html" target="_top">class
wrapper</a> facilities. If we wish to wrap <span class="bold"><b>non</b></span>-pure-virtual
functions instead, the mechanism is a bit different.
</p>
We've seen in the previous section how classes with pure virtual functions are
wrapped using Boost.Python's <a href="../../../../v2//wrapper.html" target="_top">class wrapper</a>
facilities. If we wish to wrap <span class="bold"><b>non</b></span>-pure-virtual functions instead, the
mechanism is a bit different.</p>
<p>
Recall that in the <a href="exposing.html#python.class_virtual_functions" title="Class Virtual Functions">previous
section</a>, we wrapped a class with a pure virtual function that we then
implemented in C++, or Python classes derived from it. Our base class:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Base</span>
<span class="special">{</span>
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="special">};</span>
</pre>
Recall that in the <a href="exposing.html#python.class_virtual_functions" title="Class Virtual Functions">previous section</a>, we
wrapped a class with a pure virtual function that we then implemented in C++, or
Python classes derived from it. Our base class:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> Base</span><span class="special">
{</span><span class="keyword">
virtual</span><span class="keyword"> int</span><span class="identifier"> f</span><span class="special">()</span><span class="special"> =</span><span class="number"> 0</span><span class="special">;</span><span class="special">
};</span></tt></pre>
<p>
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>
<span class="special">{</span>
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">()</span> <span class="special">{}</span>
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span>
<span class="special">};</span>
</pre>
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"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> Base</span><span class="special">
{</span><span class="keyword">
virtual</span><span class="special"> ~</span><span class="identifier">Base</span><span class="special">()</span><span class="special"> {}</span><span class="keyword">
virtual</span><span class="keyword"> int</span><span class="identifier"> f</span><span class="special">()</span><span class="special"> {</span><span class="keyword"> return</span><span class="number"> 0</span><span class="special">;</span><span class="special"> }</span><span class="special">
};</span></tt></pre>
<p>
We wrap it this way:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">override</span> <span class="identifier">f</span> <span class="special">=</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="keyword">return</span> <span class="identifier">f</span><span class="special">();</span> <span class="comment">// *note*
</span> <span class="keyword">return</span> <span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span>
<span class="special">}</span>
We wrap it this way:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> BaseWrap</span><span class="special"> :</span><span class="identifier"> Base</span><span class="special">,</span><span class="identifier"> wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span><span class="special">
{</span><span class="keyword">
int</span><span class="identifier"> f</span><span class="special">()</span><span class="special">
{</span><span class="keyword">
if</span><span class="special"> (</span><span class="identifier">override</span><span class="identifier"> f</span><span class="special"> =</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="keyword">
return</span><span class="identifier"> f</span><span class="special">();</span><span class="comment"> // *note*
</span><span class="keyword"> return</span><span class="identifier"> Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span><span class="special">
}</span><span class="keyword">
<span class="keyword">int</span> <span class="identifier">default_f</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span> <span class="special">}</span>
<span class="special">};</span>
</pre>
int</span><span class="identifier"> default_f</span><span class="special">()</span><span class="special"> {</span><span class="keyword"> return</span><span class="keyword"> this</span><span class="special">-&gt;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span><span class="special"> }</span><span class="special">
};</span></tt></pre>
<p>
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>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span><br>
<br> If you are using Microsoft Visual C++ 6 or 7, you have to rewrite
the line with the <tt class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></tt> as:<br> <br> <tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special">&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>
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="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/alert.png"></span> MSVC6/7 Workaround<p></p>
<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>
<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>.</td></tr></tbody>
</table></div>
<p>
Finally, exposing:
</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>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span><span class="special">)</span>
<span class="special">;</span>
</pre>
Finally, exposing:</p>
<pre class="programlisting"><tt class="literal"><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><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span><span class="special">)</span><span class="special">
;</span></tt></pre>
<p>
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>
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:
</p>
In Python, the results would be as expected:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> base</span><span class="special"> =</span><span class="identifier"> Base</span><span class="special">()</span><span class="special">
&gt;&gt;&gt;</span><span class="keyword"> class</span><span class="identifier"> Derived</span><span class="special">(</span><span class="identifier">Base</span><span class="special">):</span><span class="special">
...</span><span class="identifier"> def</span><span class="identifier"> f</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span><span class="special">
...</span><span class="keyword"> return</span><span class="number"> 42</span><span class="special">
...</span><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></tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">base</span> <span class="special">=</span> <span class="identifier">Base</span><span class="special">()</span>
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">class</span> <span class="identifier">Derived</span><span class="special">(</span><span class="identifier">Base</span><span class="special">):</span>
<span class="special">...</span> <span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
<span class="special">...</span> <span class="keyword">return</span> <span class="number">42</span>
<span class="special">...</span>
<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>
Calling <tt class="literal">base.f()</tt>:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
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 <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>
<span class="number">42</span>
</pre>
Calling <tt class="literal">derived.f()</tt>:</p>
<pre class="programlisting"><tt class="literal"><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><span class="number">
42</span></tt></pre>
</div>
<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><h2>
<a name="id453009"></a>
Python Operators
</h2>
<a name="id451830"></a>Python Operators</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>
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 <tt class="literal">FilePos</tt> and a set of operators
that take on FilePos instances:
</p>
<p>
</p>
<pre class="programlisting">
<span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span>
Consider a file position class <tt class="literal">FilePos</tt> and a set of operators that take
on FilePos instances:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">class</span><span class="identifier"> FilePos</span><span class="special"> {</span><span class="comment"> /*...*/</span><span class="special"> };</span><span class="identifier">
<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="keyword">int</span><span class="special">);</span>
<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">FilePos</span><span class="special">);</span>
<span class="keyword">int</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="identifier">FilePos</span><span class="special">);</span>
<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="keyword">int</span><span class="special">);</span>
<span class="identifier">FilePos</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">+=(</span><span class="identifier">FilePos</span><span class="special">&amp;,</span> <span class="keyword">int</span><span class="special">);</span>
<span class="identifier">FilePos</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">-=(</span><span class="identifier">FilePos</span><span class="special">&amp;,</span> <span class="keyword">int</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="identifier">FilePos</span><span class="special">);</span>
</pre>
FilePos</span><span class="keyword"> operator</span><span class="special">+(</span><span class="identifier">FilePos</span><span class="special">,</span><span class="keyword"> int</span><span class="special">);</span><span class="identifier">
FilePos</span><span class="keyword"> operator</span><span class="special">+(</span><span class="keyword">int</span><span class="special">,</span><span class="identifier"> FilePos</span><span class="special">);</span><span class="keyword">
int</span><span class="keyword"> operator</span><span class="special">-(</span><span class="identifier">FilePos</span><span class="special">,</span><span class="identifier"> FilePos</span><span class="special">);</span><span class="identifier">
FilePos</span><span class="keyword"> operator</span><span class="special">-(</span><span class="identifier">FilePos</span><span class="special">,</span><span class="keyword"> int</span><span class="special">);</span><span class="identifier">
FilePos</span><span class="special">&amp;</span><span class="keyword"> operator</span><span class="special">+=(</span><span class="identifier">FilePos</span><span class="special">&amp;,</span><span class="keyword"> int</span><span class="special">);</span><span class="identifier">
FilePos</span><span class="special">&amp;</span><span class="keyword"> operator</span><span class="special">-=(</span><span class="identifier">FilePos</span><span class="special">&amp;,</span><span class="keyword"> int</span><span class="special">);</span><span class="keyword">
bool</span><span class="keyword"> operator</span><span class="special">&lt;(</span><span class="identifier">FilePos</span><span class="special">,</span><span class="identifier"> FilePos</span><span class="special">);</span></tt></pre>
<p>
The class and the various operators can be mapped to Python rather easily
and intuitively:
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">FilePos</span><span class="special">&gt;(</span><span class="string">"FilePos"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">+</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __add__
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="keyword">int</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __radd__
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __sub__
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __sub__
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">+=</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __iadd__
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-=</span> <span class="identifier">other</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;())</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">&lt;</span> <span class="identifier">self</span><span class="special">);</span> <span class="comment">// __lt__
</span></pre>
The class and the various operators can be mapped to Python rather easily
and intuitively:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">FilePos</span><span class="special">&gt;(</span><span class="string">"FilePos"</span><span class="special">)</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span><span class="special"> +</span><span class="keyword"> int</span><span class="special">())</span><span class="comment"> // __add__
</span><span class="special"> .</span><span class="identifier">def</span><span class="special">(</span><span class="keyword">int</span><span class="special">()</span><span class="special"> +</span><span class="identifier"> self</span><span class="special">)</span><span class="comment"> // __radd__
</span><span class="special"> .</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span><span class="special"> -</span><span class="identifier"> self</span><span class="special">)</span><span class="comment"> // __sub__
</span><span class="special"> .</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span><span class="special"> -</span><span class="keyword"> int</span><span class="special">())</span><span class="comment"> // __sub__
</span><span class="special"> .</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span><span class="special"> +=</span><span class="keyword"> int</span><span class="special">())</span><span class="comment"> // __iadd__
</span><span class="special"> .</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span><span class="special"> -=</span><span class="identifier"> other</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;())</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span><span class="special"> &lt;</span><span class="identifier"> self</span><span class="special">);</span><span class="comment"> // __lt__
</span></tt></pre>
<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
<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>
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 <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><h2>
<a name="id453761"></a>
Special Methods
</h2>
<a name="id452516"></a>Special Methods</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
class instances. A similar set of intuitive interfaces can also be used to
wrap C++ functions that correspond to these Python <span class="emphasis"><em>special functions</em></span>.
Example:
</p>
<pre class="programlisting">
<span class="keyword">class</span> <span class="identifier">Rational</span>
<span class="special">{</span> <span class="keyword">public</span><span class="special">:</span> <span class="keyword">operator</span> <span class="keyword">double</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span> <span class="special">};</span>
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 class instances. A
similar set of intuitive interfaces can also be used to wrap C++ functions
that correspond to these Python <span class="emphasis"><em>special functions</em></span>. Example:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">class</span><span class="identifier"> Rational</span><span class="special">
{</span><span class="keyword"> operator</span><span class="keyword"> double</span><span class="special">()</span><span class="keyword"> const</span><span class="special">;</span><span class="special"> };</span><span class="identifier">
<span class="identifier">Rational</span> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">Rational</span><span class="special">,</span> <span class="identifier">Rational</span><span class="special">);</span>
<span class="identifier">Rational</span> <span class="identifier">abs</span><span class="special">(</span><span class="identifier">Rational</span><span class="special">);</span>
<span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">ostream</span><span class="special">&amp;,</span><span class="identifier">Rational</span><span class="special">);</span>
Rational</span><span class="identifier"> pow</span><span class="special">(</span><span class="identifier">Rational</span><span class="special">,</span><span class="identifier"> Rational</span><span class="special">);</span><span class="identifier">
Rational</span><span class="identifier"> abs</span><span class="special">(</span><span class="identifier">Rational</span><span class="special">);</span><span class="identifier">
ostream</span><span class="special">&amp;</span><span class="keyword"> operator</span><span class="special">&lt;&lt;(</span><span class="identifier">ostream</span><span class="special">&amp;,</span><span class="identifier">Rational</span><span class="special">);</span><span class="identifier">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Rational</span><span class="special">&gt;(</span><span class="string">"Rational"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">float_</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __float__
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">pow</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">other</span><span class="special">&lt;</span><span class="identifier">Rational</span><span class="special">&gt;))</span> <span class="comment">// __pow__
</span> <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __abs__
</span> <span class="special">.</span><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> <span class="comment">// __str__
</span> <span class="special">;</span>
</pre>
class_</span><span class="special">&lt;</span><span class="identifier">Rational</span><span class="special">&gt;()</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">float_</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span><span class="comment"> // __float__
</span><span class="special"> .</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">pow</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span><span class="identifier"> other</span><span class="special">&lt;</span><span class="identifier">Rational</span><span class="special">&gt;))</span><span class="comment"> // __pow__
</span><span class="special"> .</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span><span class="comment"> // __abs__
</span><span class="special"> .</span><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><span class="comment"> // __str__
</span><span class="special"> ;</span></tt></pre>
<p>
Need we say more?
</p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> What is the business of <tt class="computeroutput"><span class="keyword">operator</span><span class="special">&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>
Need we say more?</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/note.png"></span> What is the business of <tt class="literal">operator&lt;&lt;</tt><tt class="literal">.def(str(self))</tt>?
Well, the method <tt class="literal">str</tt> requires the <tt class="literal">operator&lt;&lt;</tt> to do its work (i.e.
<tt class="literal">operator&lt;&lt;</tt> is used by the method defined by def(str(self)).</td></tr></tbody>
</table></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright © 2002-2005 Joel
de Guzman, David Abrahams</small></td>
<td align="right"><small>Copyright © 2002-2004 Joel de Guzman, David Abrahams</small></td>
</tr></table>
<hr>
<div class="spirit-nav">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -14,9 +11,9 @@
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td valign="top"><img alt="boost.png (6897 bytes)" 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="../../../../../../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>
@@ -35,568 +32,444 @@
<dt><span class="section"><a href="functions.html#python.auto_overloading">Auto-Overloading</a></span></dt>
</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.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="emphasis"><em>Read on...</em></span>
</p></blockquote></div>
In this chapter, we'll look at Boost.Python powered functions in closer
detail. We shall see some facilities to make exposing C++ functions to
Python safe from potential pifalls such as dangling pointers and
references. We shall also see facilities that will make it even easier for
us to expose C++ functions that take advantage of C++ features such as
overloading and default arguments.</p>
<div class="blockquote"><blockquote class="blockquote"><p><span class="emphasis"><em>Read on...</em></span></p></blockquote></div>
<p>
But before you do, you might want to fire up Python 2.2 or later and type
<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
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
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"><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!
</pre>
But before you do, you might want to fire up Python 2.2 or later and type
<tt class="literal">&gt;&gt;&gt; import this</tt>.</p>
<pre class="programlisting"><tt class="literal"> &gt;&gt;&gt; import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
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"><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!
</tt></pre>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.call_policies"></a>Call Policies</h3></div></div></div>
<p>
In C++, we often deal with arguments and return types such as pointers and
references. Such primitive types are rather, ummmm, low level and they really
don't tell us much. At the very least, we don't know the owner of the pointer
or the referenced object. No wonder languages such as Java and Python never
deal with such low level entities. In C++, it's usually considered a good
practice to use smart pointers which exactly describe ownership semantics.
Still, even good C++ interfaces use raw references and pointers sometimes,
so Boost.Python must deal with them. To do this, it may need your help. Consider
the following C++ function:
</p>
<pre class="programlisting">
<span class="identifier">X</span><span class="special">&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>
</pre>
In C++, we often deal with arguments and return types such as pointers
and references. Such primitive types are rather, ummmm, low level and
they really don't tell us much. At the very least, we don't know the
owner of the pointer or the referenced object. No wonder languages
such as Java and Python never deal with such low level entities. In
C++, it's usually considered a good practice to use smart pointers
which exactly describe ownership semantics. Still, even good C++
interfaces use raw references and pointers sometimes, so Boost.Python
must deal with them. To do this, it may need your help. Consider the
following C++ function:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
How should the library wrap this function? A naive approach builds a Python
X object around result reference. This strategy might or might not work out.
Here's an example where it didn't
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> # <span class="identifier">x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">y</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> # <span class="identifier">CRASH</span><span class="special">!</span>
</pre>
How should the library wrap this function? A naive approach builds a
Python X object around result reference. This strategy might or might
not work out. Here's an example where it didn't</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> x</span><span class="special"> =</span><span class="identifier"> f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span><span class="identifier"> z</span><span class="special">)</span> #<span class="identifier"> x</span><span class="identifier"> refers</span><span class="identifier"> to</span><span class="identifier"> some</span><span class="identifier"> C</span><span class="special">++</span><span class="identifier"> X</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> del</span><span class="identifier"> y</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> #<span class="identifier"> CRASH</span><span class="special">!</span></tt></pre>
<p>
What's the problem?
</p>
What's the problem?</p>
<p>
Well, what if f() was implemented as shown below:
</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>
<span class="special">{</span>
<span class="identifier">y</span><span class="special">.</span><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
<span class="special">}</span>
</pre>
Well, what if f() was implemented as shown below:</p>
<pre class="programlisting"><tt class="literal"><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><span class="special">
{</span><span class="identifier">
y</span><span class="special">.</span><span class="identifier">z</span><span class="special"> =</span><span class="identifier"> z</span><span class="special">;</span><span class="keyword">
return</span><span class="identifier"> y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span><span class="special">
}</span></tt></pre>
<p>
The problem is that the lifetime of result X&amp; is tied to the lifetime
of y, because the f() returns a reference to a member of the y object. This
idiom is is not uncommon and perfectly acceptable in the context of C++.
However, Python users should not be able to crash the system just by using
our C++ interface. In this case deleting y will invalidate the reference
to X. We have a dangling reference.
</p>
The problem is that the lifetime of result X&amp; is tied to the lifetime
of y, because the f() returns a reference to a member of the y
object. This idiom is is not uncommon and perfectly acceptable in the
context of C++. However, Python users should not be able to crash the
system just by using our C++ interface. In this case deleting y will
invalidate the reference to X. We have a dangling reference.</p>
<p>
Here's what's happening:
</p>
Here's what's happening:</p>
<div class="orderedlist"><ol type="1">
<li>
<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>
<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 <tt class="literal">y.x</tt> is returned
</li>
A reference to <tt class="literal">y.x</tt> is returned
</li>
<li>
<tt class="literal">y</tt> is deleted. <tt class="literal">x</tt> is a dangling reference
</li>
</li>
<li>
<tt class="literal">x.some_method()</tt> is called
</li>
</li>
<li><span class="bold"><b>BOOM!</b></span></li>
</ol></div>
<p>
We could copy result into a new object:
</p>
We could copy result into a new object:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span><span class="identifier"> z</span><span class="special">).</span><span class="identifier">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> #<span class="identifier"> Result</span><span class="identifier"> disappears</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> y</span><span class="special">.</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span>       #<span class="identifier"> No</span><span class="identifier"> crash</span><span class="special">,</span><span class="identifier"> but</span><span class="identifier"> still</span><span class="identifier"> bad</span><span class="number">
3.14</span></tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">).</span><span class="identifier">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="comment"># Result disappears
</span><span class="special">&gt;&gt;&gt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="comment"># No crash, but still bad
</span><span class="number">3.14</span>
</pre>
This is not really our intent of our C++ interface. We've broken our
promise that the Python interface should reflect the C++ interface as
closely as possible.</p>
<p>
This is not really our intent of our C++ interface. We've broken our promise
that the Python interface should reflect the C++ interface as closely as
possible.
</p>
Our problems do not end there. Suppose Y is implemented as follows:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> Y</span><span class="special">
{</span><span class="identifier">
X</span><span class="identifier"> x</span><span class="special">;</span><span class="identifier"> Z</span><span class="special">*</span><span class="identifier"> z</span><span class="special">;</span><span class="keyword">
int</span><span class="identifier"> z_value</span><span class="special">()</span><span class="special"> {</span><span class="keyword"> return</span><span class="identifier"> z</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">();</span><span class="special"> }</span><span class="special">
};</span></tt></pre>
<p>
Our problems do not end there. Suppose Y is implemented as follows:
</p>
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"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> x</span><span class="special"> =</span><span class="identifier"> f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span><span class="identifier"> z</span><span class="special">)</span> #<span class="identifier"> y</span><span class="identifier"> refers</span><span class="identifier"> to</span><span class="identifier"> z</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> del</span><span class="identifier"> z</span>       #<span class="identifier"> Kill</span><span class="identifier"> the</span><span class="identifier"> z</span><span class="identifier"> object</span><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="identifier"> CRASH</span><span class="special">!</span></tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">Y</span>
<span class="special">{</span>
<span class="identifier">X</span> <span class="identifier">x</span><span class="special">;</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">z_value</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">z</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">();</span> <span class="special">}</span>
<span class="special">};</span>
</pre>
For reference, here's the implementation of <tt class="literal">f</tt> again:</p>
<pre class="programlisting"><tt class="literal"><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><span class="special">
{</span><span class="identifier">
y</span><span class="special">.</span><span class="identifier">z</span><span class="special"> =</span><span class="identifier"> z</span><span class="special">;</span><span class="keyword">
return</span><span class="identifier"> y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span><span class="special">
}</span></tt></pre>
<p>
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">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> # <span class="identifier">y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">z</span> # <span class="identifier">Kill</span> <span class="identifier">the</span> <span class="identifier">z</span> <span class="identifier">object</span>
<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="identifier">CRASH</span><span class="special">!</span>
</pre>
<p>
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>
<span class="special">{</span>
<span class="identifier">y</span><span class="special">.</span><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
Here's what's happening:
</p>
Here's what's happening:</p>
<div class="orderedlist"><ol type="1">
<li>
<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>
<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 <tt class="literal">z</tt> is held by <tt class="literal">y</tt>
A pointer to <tt class="literal">z</tt> is held by <tt class="literal">y</tt>
</li>
<li>
A reference to <tt class="literal">y.x</tt> is returned
</li>
A reference to <tt class="literal">y.x</tt> is returned
</li>
<li>
<tt class="literal">z</tt> is deleted. <tt class="literal">y.z</tt> is a dangling pointer
</li>
</li>
<li>
<tt class="literal">y.z_value()</tt> is called
</li>
</li>
<li>
<tt class="literal">z-&gt;value()</tt> is called
</li>
</li>
<li><span class="bold"><b>BOOM!</b></span></li>
</ol></div>
<a name="call_policies.call_policies"></a><h2>
<a name="id455614"></a>
Call Policies
</h2>
<a name="id454162"></a>Call Policies</h2>
<p>
Call Policies may be used in situations such as the example detailed above.
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">
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span>
<span class="identifier">return_internal_reference</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span>
<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>
Call Policies may be used in situations such as the example detailed above.
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"><tt class="literal"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> f</span><span class="special">,</span><span class="identifier">
return_internal_reference</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span><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></tt></pre>
<p>
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>
What are the <tt class="literal">1</tt> and <tt class="literal">2</tt> parameters, you ask?</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">return_internal_reference</span><span class="special">&lt;</span><span class="number">1</span></tt></pre>
<p>
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>
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"><tt class="literal"><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></tt></pre>
<p>
Informs Boost.Python that the lifetime of the argument indicated by ward
(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>
Informs Boost.Python that the lifetime of the argument indicated by ward
(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
or more policies can be composed by chaining. Here's the general syntax:
</p>
<pre class="programlisting">
<span class="identifier">policy1</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...,</span>
<span class="identifier">policy2</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...,</span>
<span class="identifier">policy3</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...&gt;</span> <span class="special">&gt;</span> <span class="special">&gt;</span>
</pre>
It is also important to note that we have defined two policies above. Two
or more policies can be composed by chaining. Here's the general syntax:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">policy1</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...,</span><span class="identifier">
policy2</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...,</span><span class="identifier">
policy3</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...&gt;</span><span class="special"> &gt;</span><span class="special"> &gt;</span></tt></pre>
<p>
Here is the list of predefined call policies. A complete reference detailing
these can be found <a href="../../../../v2/reference.html#models_of_call_policies" target="_top">here</a>.
</p>
Here is the list of predefined call policies. A complete reference detailing
these can be found <a href="../../../../v2/reference.html#models_of_call_policies" target="_top">here</a>.</p>
<div class="itemizedlist"><ul type="disc">
<li>
<span class="bold"><b>with_custodian_and_ward</b></span><br> Ties lifetimes
of the arguments
</li>
<li>
<span class="bold"><b>with_custodian_and_ward_postcall</b></span><br>
Ties lifetimes of the arguments and results
</li>
<li>
<span class="bold"><b>return_internal_reference</b></span><br> Ties lifetime
of one argument to that of result
</li>
<li>
<span class="bold"><b>return_value_policy&lt;T&gt; with T one of:</b></span><br>
<span class="bold"><b>with_custodian_and_ward</b></span><p></p>
Ties lifetimes of the arguments
</li>
<li>
<span class="bold"><b>reference_existing_object</b></span><br> naive
(dangerous) approach
</li>
<li>
<span class="bold"><b>copy_const_reference</b></span><br> Boost.Python
v1 approach
</li>
<li>
<span class="bold"><b>copy_non_const_reference</b></span><br>
<span class="bold"><b>with_custodian_and_ward_postcall</b></span><p></p>
Ties lifetimes of the arguments and results
</li>
<li>
<span class="bold"><b>manage_new_object</b></span><br> Adopt a pointer
and hold the instance
</li>
<span class="bold"><b>return_internal_reference</b></span><p></p>
Ties lifetime of one argument to that of result
</li>
<li>
<span class="bold"><b>return_value_policy&lt;T&gt; with T one of:</b></span><p></p>
</li>
<li>
<span class="bold"><b>reference_existing_object</b></span><p></p>
naive (dangerous) approach
</li>
<li>
<span class="bold"><b>copy_const_reference</b></span><p></p>
Boost.Python v1 approach
</li>
<li>
<span class="bold"><b>copy_non_const_reference</b></span><p></p>
</li>
<li>
<span class="bold"><b>manage_new_object</b></span><p></p>
Adopt a pointer and hold the instance
</li>
</ul></div>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><b>Remember the Zen, Luke:</b></span><br>
<br> "Explicit is better than implicit"<br> "In the face
of ambiguity, refuse the temptation to guess"<br>
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/smiley.png"></span><span class="bold"><b>Remember the Zen, Luke:</b></span><p></p>
<p></p>
"Explicit is better than implicit"<p></p>
"In the face of ambiguity, refuse the temptation to guess"<p></p>
</td></tr></tbody>
</table></div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.overloading"></a>Overloading</h3></div></div></div>
<p>
The following illustrates a scheme for manually wrapping an overloaded member
functions. Of course, the same technique can be applied to wrapping overloaded
non-member functions.
</p>
The following illustrates a scheme for manually wrapping an overloaded
member functions. Of course, the same technique can be applied to wrapping
overloaded non-member functions.</p>
<p>
We have here our C++ class:
</p>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">X</span>
<span class="special">{</span>
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
<span class="special">}</span>
We have here our C++ class:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> X</span><span class="special">
{</span><span class="keyword">
bool</span><span class="identifier"> f</span><span class="special">(</span><span class="keyword">int</span><span class="identifier"> a</span><span class="special">)</span><span class="special">
{</span><span class="keyword">
return</span><span class="keyword"> true</span><span class="special">;</span><span class="special">
}</span><span class="keyword">
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">b</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
<span class="special">}</span>
bool</span><span class="identifier"> f</span><span class="special">(</span><span class="keyword">int</span><span class="identifier"> a</span><span class="special">,</span><span class="keyword"> double</span><span class="identifier"> b</span><span class="special">)</span><span class="special">
{</span><span class="keyword">
return</span><span class="keyword"> true</span><span class="special">;</span><span class="special">
}</span><span class="keyword">
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">b</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">c</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
<span class="special">}</span>
bool</span><span class="identifier"> f</span><span class="special">(</span><span class="keyword">int</span><span class="identifier"> a</span><span class="special">,</span><span class="keyword"> double</span><span class="identifier"> b</span><span class="special">,</span><span class="keyword"> char</span><span class="identifier"> c</span><span class="special">)</span><span class="special">
{</span><span class="keyword">
return</span><span class="keyword"> true</span><span class="special">;</span><span class="special">
}</span><span class="keyword">
<span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">c</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span> <span class="special">+</span> <span class="identifier">c</span><span class="special">;</span>
<span class="special">};</span>
<span class="special">};</span>
</pre>
int</span><span class="identifier"> f</span><span class="special">(</span><span class="keyword">int</span><span class="identifier"> a</span><span class="special">,</span><span class="keyword"> int</span><span class="identifier"> b</span><span class="special">,</span><span class="keyword"> int</span><span class="identifier"> c</span><span class="special">)</span><span class="special">
{</span><span class="keyword">
return</span><span class="identifier"> a</span><span class="special"> +</span><span class="identifier"> b</span><span class="special"> +</span><span class="identifier"> c</span><span class="special">;</span><span class="special">
};</span><span class="special">
};</span></tt></pre>
<p>
Class X has 4 overloaded functions. We shall start by introducing some member
function pointer variables:
</p>
<pre class="programlisting">
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</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="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx3</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="special">)=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
<span class="keyword">int</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx4</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
</pre>
Class X has 4 overloaded functions. We shall start by introducing some
member function pointer variables:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">bool</span><span class="special"> (</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span><span class="special"> =</span><span class="special"> &amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span><span class="keyword">
bool</span><span class="special"> (</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</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="special"> =</span><span class="special"> &amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span><span class="keyword">
bool</span><span class="special"> (</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx3</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="special">)=</span><span class="special"> &amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span><span class="keyword">
int</span><span class="special"> (</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx4</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword"> int</span><span class="special">,</span><span class="keyword"> int</span><span class="special">)</span><span class="special"> =</span><span class="special"> &amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span></tt></pre>
<p>
With these in hand, we can proceed to define and wrap this for Python:
</p>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx3</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx4</span><span class="special">)</span>
</pre>
With these in hand, we can proceed to define and wrap this for Python:</p>
<pre class="programlisting"><tt class="literal"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> fx1</span><span class="special">)</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> fx2</span><span class="special">)</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> fx3</span><span class="special">)</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> fx4</span><span class="special">)</span></tt></pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<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 <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>
Boost.Python wraps (member) function pointers. Unfortunately, C++ function
pointers carry no default argument info. Take a function <tt class="literal">f</tt> with default
arguments:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
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>
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"><tt class="literal"><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></tt></pre>
<p>
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">
<span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!
</span></pre>
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"><tt class="literal"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> f</span><span class="special">);</span><span class="comment"> // defaults lost!
</span></tt></pre>
<p>
Because of this, when wrapping C++ code, we had to resort to manual wrapping
as outlined in the <a href="functions.html#python.overloading" title="Overloading">previous section</a>,
or writing thin wrappers:
</p>
<pre class="programlisting">
<span class="comment">// write "thin wrappers"
</span><span class="keyword">int</span> <span class="identifier">f1</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">f2</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">);</span> <span class="special">}</span>
Because of this, when wrapping C++ code, we had to resort to manual
wrapping as outlined in the <a href="functions.html#python.overloading" title="Overloading">previous section</a>, or
writing thin wrappers:</p>
<pre class="programlisting"><tt class="literal"><span class="comment">// write "thin wrappers"
</span><span class="keyword">int</span><span class="identifier"> f1</span><span class="special">(</span><span class="keyword">int</span><span class="identifier"> x</span><span class="special">)</span><span class="special"> {</span><span class="identifier"> f</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span><span class="special"> }</span><span class="keyword">
int</span><span class="identifier"> f2</span><span class="special">(</span><span class="keyword">int</span><span class="identifier"> x</span><span class="special">,</span><span class="keyword"> double</span><span class="identifier"> y</span><span class="special">)</span><span class="special"> {</span><span class="identifier"> f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">);</span><span class="special"> }</span><span class="comment">
<span class="comment">/*...*/</span>
/*...*/
<span class="comment">// in module init
</span> <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// all arguments
</span> <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f2</span><span class="special">);</span> <span class="comment">// two arguments
</span> <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f1</span><span class="special">);</span> <span class="comment">// one argument
</span></pre>
// in module init
</span><span class="identifier"> def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> f</span><span class="special">);</span><span class="comment"> // all arguments
</span><span class="identifier"> def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> f2</span><span class="special">);</span><span class="comment"> // two arguments
</span><span class="identifier"> def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> f1</span><span class="special">);</span><span class="comment"> // one argument
</span></tt></pre>
<p>
When you want to wrap functions (or member functions) that either:
</p>
When you want to wrap functions (or member functions) that either:</p>
<div class="itemizedlist"><ul type="disc">
<li>
have default arguments, or
</li>
have default arguments, or
</li>
<li>
are overloaded with a common sequence of initial arguments
</li>
are overloaded with a common sequence of initial arguments
</li>
</ul></div>
<a name="default_arguments.boost_python_function_overloads"></a><h2>
<a name="id457647"></a>
BOOST_PYTHON_FUNCTION_OVERLOADS
</h2>
<a name="id455979"></a>BOOST_PYTHON_FUNCTION_OVERLOADS</h2>
<p>
Boost.Python now has a way to make it easier. For instance, given a function:
</p>
<pre class="programlisting">
<span class="keyword">int</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">c</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">3</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">/*...*/</span>
<span class="special">}</span>
</pre>
Boost.Python now has a way to make it easier. For instance, given a function:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">int</span><span class="identifier"> foo</span><span class="special">(</span><span class="keyword">int</span><span class="identifier"> a</span><span class="special">,</span><span class="keyword"> char</span><span class="identifier"> b</span><span class="special"> =</span><span class="number"> 1</span><span class="special">,</span><span class="keyword"> unsigned</span><span class="identifier"> c</span><span class="special"> =</span><span class="number"> 2</span><span class="special">,</span><span class="keyword"> double</span><span class="identifier"> d</span><span class="special"> =</span><span class="number"> 3</span><span class="special">)</span><span class="special">
{</span><span class="comment">
/*...*/</span><span class="special">
}</span></tt></pre>
<p>
The macro invocation:
</p>
<pre class="programlisting">
<span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
</pre>
The macro invocation:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span><span class="identifier"> foo</span><span class="special">,</span><span class="number"> 1</span><span class="special">,</span><span class="number"> 4</span><span class="special">)</span></tt></pre>
<p>
will automatically create the thin wrappers for us. This macro will create
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 <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>
will automatically create the thin wrappers for us. This macro will create
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 <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"><tt class="literal"><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></tt></pre>
<a name="default_arguments.boost_python_member_function_overloads"></a><h2>
<a name="id457963"></a>
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
</h2>
<a name="id456259"></a>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</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
Python. Then again, we have the same inconveniences as before when default
arguments or overloads with a common sequence of initial arguments come into
play. Another macro is provided to make this a breeze.
</p>
Objects here, objects there, objects here there everywhere. More frequently
than anything else, we need to expose member functions of our classes to
Python. Then again, we have the same inconveniences as before when default
arguments or overloads with a common sequence of initial arguments come
into play. Another macro is provided to make this a breeze.</p>
<p>
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>
<pre class="programlisting">
<span class="keyword">struct</span> <span class="identifier">george</span>
<span class="special">{</span>
<span class="keyword">void</span>
<span class="identifier">wack_em</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">c</span> <span class="special">=</span> <span class="char">'x'</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">/*...*/</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
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>
<pre class="programlisting"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> george</span><span class="special">
{</span><span class="keyword">
void</span><span class="identifier">
wack_em</span><span class="special">(</span><span class="keyword">int</span><span class="identifier"> a</span><span class="special">,</span><span class="keyword"> int</span><span class="identifier"> b</span><span class="special"> =</span><span class="number"> 0</span><span class="special">,</span><span class="keyword"> char</span><span class="identifier"> c</span><span class="special"> =</span><span class="char"> 'x'</span><span class="special">)</span><span class="special">
{</span><span class="comment">
/*...*/</span><span class="special">
}</span><span class="special">
};</span></tt></pre>
<p>
The macro invocation:
</p>
<pre class="programlisting">
<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>
The macro invocation:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
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 <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>
</pre>
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
<tt class="literal">george_overloads</tt> that can then be used as an argument to <tt class="literal">def(...)</tt>:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
See the <a href="../../../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec" target="_top">overloads
reference</a> for details.
</p>
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><h2>
<a name="id458323"></a>
init and optional
</h2>
<a name="id456586"></a>init and optional</h2>
<p>
A similar facility is provided for class constructors, again, with default
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">
<span class="keyword">struct</span> <span class="identifier">X</span>
<span class="special">{</span>
<span class="identifier">X</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="char">'D'</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">c</span> <span class="special">=</span> <span class="string">"constructor"</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">);</span>
<span class="comment">/*...*/</span>
<span class="special">}</span>
</pre>
A similar facility is provided for class constructors, again, with
default 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"><tt class="literal"><span class="keyword">struct</span><span class="identifier"> X</span><span class="special">
{</span><span class="identifier">
X</span><span class="special">(</span><span class="keyword">int</span><span class="identifier"> a</span><span class="special">,</span><span class="keyword"> char</span><span class="identifier"> b</span><span class="special"> =</span><span class="char"> 'D'</span><span class="special">,</span><span class="identifier"> std</span><span class="special">::</span><span class="identifier">string</span><span class="identifier"> c</span><span class="special"> =</span><span class="string"> "constructor"</span><span class="special">,</span><span class="keyword"> double</span><span class="identifier"> d</span><span class="special"> =</span><span class="number"> 0.0</span><span class="special">);</span><span class="comment">
/*...*/</span><span class="special">
}</span></tt></pre>
<p>
You can easily add this constructor to Boost.Python in one shot:
</p>
<pre class="programlisting">
<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>
You can easily add this constructor to Boost.Python in one shot:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
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>
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>
<div class="section" lang="en">
<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 <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>
and <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> can also be
used for overloaded functions and member functions with a common sequence
of initial arguments. Here is an example:
</p>
<pre class="programlisting">
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
<span class="special">{</span>
<span class="comment">/*...*/</span>
<span class="special">}</span>
It was mentioned in passing in the previous section that
<tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt> and <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
can also be used for overloaded functions and member functions with a
common sequence of initial arguments. Here is an example:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">void</span><span class="identifier"> foo</span><span class="special">()</span><span class="special">
{</span><span class="comment">
/*...*/</span><span class="special">
}</span><span class="keyword">
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">a</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">/*...*/</span>
<span class="special">}</span>
void</span><span class="identifier"> foo</span><span class="special">(</span><span class="keyword">bool</span><span class="identifier"> a</span><span class="special">)</span><span class="special">
{</span><span class="comment">
/*...*/</span><span class="special">
}</span><span class="keyword">
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">/*...*/</span>
<span class="special">}</span>
void</span><span class="identifier"> foo</span><span class="special">(</span><span class="keyword">bool</span><span class="identifier"> a</span><span class="special">,</span><span class="keyword"> int</span><span class="identifier"> b</span><span class="special">)</span><span class="special">
{</span><span class="comment">
/*...*/</span><span class="special">
}</span><span class="keyword">
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">c</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">/*...*/</span>
<span class="special">}</span>
</pre>
void</span><span class="identifier"> foo</span><span class="special">(</span><span class="keyword">bool</span><span class="identifier"> a</span><span class="special">,</span><span class="keyword"> int</span><span class="identifier"> b</span><span class="special">,</span><span class="keyword"> char</span><span class="identifier"> c</span><span class="special">)</span><span class="special">
{</span><span class="comment">
/*...*/</span><span class="special">
}</span></tt></pre>
<p>
Like in the previous section, we can generate thin wrappers for these overloaded
functions in one-shot:
</p>
<pre class="programlisting">
<span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
</pre>
Like in the previous section, we can generate thin wrappers for these
overloaded functions in one-shot:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span><span class="identifier"> foo</span><span class="special">,</span><span class="number"> 0</span><span class="special">,</span><span class="number"> 3</span><span class="special">)</span></tt></pre>
<p>
Then...
</p>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">void</span><span class="special">(*)(</span><span class="keyword">bool</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">))</span><span class="number">0</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
</pre>
Then...</p>
<pre class="programlisting"><tt class="literal"><span class="special">.</span><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></tt></pre>
<p>
Notice though that we have a situation now where we have a minimum of zero
(0) arguments and a maximum of 3 arguments.
</p>
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><h2>
<a name="id459095"></a>
Manual Wrapping
</h2>
<a name="id457233"></a>Manual Wrapping</h2>
<p>
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>
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 <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 <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">
<span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">xf_overloads</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
</pre>
Actually, we can mix and match manual wrapping of overloaded functions and
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 <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"><tt class="literal"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">xf_overloads</span><span class="special">,</span><span class="identifier"> f</span><span class="special">,</span><span class="number"> 1</span><span class="special">,</span><span class="number"> 4</span><span class="special">)</span></tt></pre>
<p>
Create a member function pointers as above for both X::f overloads:
</p>
<pre class="programlisting">
<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</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="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
<span class="keyword">int</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
</pre>
Create a member function pointers as above for both X::f overloads:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">bool</span><span class="special"> (</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</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="special">)</span><span class="special"> =</span><span class="special"> &amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span><span class="keyword">
int</span><span class="special"> (</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword"> int</span><span class="special">,</span><span class="keyword"> int</span><span class="special">)</span><span class="special"> =</span><span class="special"> &amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span></tt></pre>
<p>
Then...
</p>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">,</span> <span class="identifier">xf_overloads</span><span class="special">());</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
</pre>
Then...</p>
<pre class="programlisting"><tt class="literal"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> fx1</span><span class="special">,</span><span class="identifier"> xf_overloads</span><span class="special">());</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span><span class="identifier"> fx2</span><span class="special">)</span></tt></pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright © 2002-2005 Joel
de Guzman, David Abrahams</small></td>
<td align="right"><small>Copyright © 2002-2004 Joel de Guzman, David Abrahams</small></td>
</tr></table>
<hr>
<div class="spirit-nav">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -14,9 +11,9 @@
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td valign="top"><img alt="boost.png (6897 bytes)" 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="../../../../../../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>
@@ -29,258 +26,201 @@
<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><h2>
<a name="id377427"></a>
From Start To Finish
</h2>
<a name="id446728"></a>From Start To Finish</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"><b>bjam</b></span>.
</p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Building without bjam</b></span><br>
<br> Besides bjam, there are of course other ways to get your module built.
What's written here should not be taken as "the one and only way".
There are of course other build tools apart from <tt class="literal">bjam</tt>.<br>
<br> Take note however that the preferred build tool for Boost.Python is
bjam. There are so many ways to set up the build incorrectly. Experience shows
that 90% of the "I can't build Boost.Python" problems come from people
who had to use a different tool.
</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"><b>bjam</b></span>.</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/note.png"></span><span class="bold"><b>Building without bjam</b></span><p></p>
<p></p>
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>
<p></p>
Take note however that the preferred build tool for Boost.Python is bjam.
There are so many ways to set up the build incorrectly. Experience shows
that 90% of the "I can't build Boost.Python" problems come from people
who had to use a different tool.
</td></tr></tbody>
</table></div>
<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>
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>
boost_python.dll
</li>
<li>
hello.pyd
</li>
hello.pyd
</li>
</ul></div>
<p>
if you are on Windows, and
</p>
if you are on Windows, and</p>
<div class="itemizedlist"><ul type="disc">
<li>
libboost_python.so
</li>
libboost_python.so
</li>
<li>
hello.so
</li>
hello.so
</li>
</ul></div>
<p>
if you are on Unix.
</p>
if you are on Unix.</p>
<p>
The tutorial example can be found in the directory: <tt class="literal">libs/python/example/tutorial</tt>.
There, you can find:
</p>
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">
<li>
hello.cpp
</li>
<li>
Jamfile
</li>
</ul></div>
<p>
The <tt class="literal">hello.cpp</tt> file is our C++ hello world example. The
<tt class="literal">Jamfile</tt> is a minimalist <span class="emphasis"><em>bjam</em></span> script
that builds the DLLs for us.
</p>
<p>
Before anything else, you should have the bjam executable in your boost directory
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><h2>
<a name="id377613"></a>
Let's Jam!
</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.
<tt class="literal">project-root</tt> 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 <tt class="literal">path-global BOOST_ROOT</tt> to where your boost
root directory is. The file has <a href="../../../../../example/tutorial/Jamrules" target="_top">detailed
instructions</a> you can follow.
</p>
<p>
Then we will import the definitions needed by Python modules:
</p>
<pre class="programlisting">import python ;
</pre>
<p>
Finally we declare our <tt class="literal">hello</tt> 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><h2>
<a name="id377751"></a>
Running bjam
</h2>
<p>
<span class="emphasis"><em>bjam</em></span> is run using your operating system's command line
interpreter.
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
Start it up.
</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 <tt class="literal">Vcvars32.bat</tt> batch
file. For instance:
</p>
<pre class="programlisting">C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat
</pre>
<p>
Some environment variables will have to be setup for proper building of our
Python modules. Example:
</p>
<pre class="programlisting">set PYTHON_ROOT=c:/dev/tools/python
set PYTHON_VERSION=2.2
</pre>
<p>
The above assumes that the Python installation is in <tt class="literal">c:/dev/tools/python</tt>
and that we are using Python version 2.2. You'll have to tweak these appropriately.
</p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> Be sure not to include a third number, e.g. <span class="bold"><b>not</b></span> "2.2.1", even if that's the version you
have.
</p>
<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.
</p>
<p>
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">"Jamfile"</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>
</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
...patience...
...found 1703 targets...
...updating 40 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>
<li>
boost_python.dll
</li>
<li>
hello.pyd
</li>
Jamfile
</li>
</ul></div>
<p>
if you are on Windows, and
</p>
The <tt class="literal">hello.cpp</tt> file is our C++ hello world example. The <tt class="literal">Jamfile</tt> is a
minimalist <span class="emphasis"><em>bjam</em></span> script that builds the DLLs for us.</p>
<p>
Before anything else, you should have the bjam executable in your boost
directory 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><h2>
<a name="id377058"></a>Let's Jam!</h2>
<p><span class="inlinemediaobject"><img src="../images/jam.png"></span></p>
<p>
Here is our minimalist Jamfile:</p>
<pre class="programlisting"><tt class="literal"> subproject libs/python/example/tutorial ;
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
extension hello # Declare a Python extension called hello
: hello.cpp # source
&lt;dll&gt;../../build/boost_python # dependencies
;
</tt></pre>
<p>
First, we need to specify our location in the boost project hierarchy.
It so happens that the tutorial example is located in <tt class="literal">/libs/python/example/tutorial</tt>.
Thus:</p>
<pre class="programlisting"><tt class="literal"> subproject libs/python/example/tutorial ;
</tt></pre>
<p>
Then we will include the definitions needed by Python modules:</p>
<pre class="programlisting"><tt class="literal"> SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
</tt></pre>
<p>
Finally we declare our <tt class="literal">hello</tt> extension:</p>
<pre class="programlisting"><tt class="literal"> extension hello # Declare a Python extension called hello
: hello.cpp # source
&lt;dll&gt;../../build/boost_python # dependencies
;
</tt></pre>
<a name="hello.running_bjam"></a><h2>
<a name="id377153"></a>Running bjam</h2>
<p><span class="emphasis"><em>bjam</em></span> is run using your operating system's command line interpreter.</p>
<div class="blockquote"><blockquote class="blockquote"><p>Start it up.</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 <tt class="literal">Vcvars32.bat</tt> batch
file. For instance:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">C</span><span class="special">:\</span><span class="identifier">Program</span><span class="identifier"> Files</span><span class="special">\</span><span class="identifier">Microsoft</span><span class="identifier"> Visual</span><span class="identifier"> Studio</span><span class="special">\</span><span class="identifier">VC98</span><span class="special">\</span><span class="identifier">bin</span><span class="special">\</span><span class="identifier">Vcvars32</span><span class="special">.</span><span class="identifier">bat</span></tt></pre>
<p>
Some environment variables will have to be setup for proper building of our
Python modules. Example:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">set</span><span class="identifier"> PYTHON_ROOT</span><span class="special">=</span><span class="identifier">c</span><span class="special">:/</span><span class="identifier">dev</span><span class="special">/</span><span class="identifier">tools</span><span class="special">/</span><span class="identifier">python</span><span class="identifier">
set</span><span class="identifier"> PYTHON_VERSION</span><span class="special">=</span><span class="number">2.2</span></tt></pre>
<p>
The above assumes that the Python installation is in <tt class="literal">c:/dev/tools/python</tt>
and that we are using Python version 2.2. You'll have to tweak this path
appropriately.</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/tip.png"></span> Be sure not to include a third number, e.g. <span class="bold"><b>not</b></span> "2.2.1",
even if that's the version you have.</td></tr></tbody>
</table></div>
<p>
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">"Jamfile"</tt> is situated.</p>
<p>
Finally:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">bjam</span><span class="special"> -</span><span class="identifier">sTOOLS</span><span class="special">=</span><span class="identifier">msvc</span></tt></pre>
<p>
We are again assuming that we are using Microsoft Visual C++ version 6. 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"><tt class="literal"> cd C:\dev\boost\libs\python\example\tutorial
bjam -sTOOLS=msvc
...patience...
...found 1703 targets...
...updating 40 targets...
</tt></pre>
<p>
And so on... Finally:</p>
<pre class="programlisting"><tt class="literal"> vc-C++ ........\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
runtime-link-dynamic\hello.obj
hello.cpp
vc-Link ........\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
runtime-link-dynamic\hello.pyd ........\libs\python\example\tutorial\bin\
hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib
Creating library ........\libs\python\example\tutorial\bin\hello.pyd\
msvc\debug\runtime-link-dynamic\hello.lib and object ........\libs\python\
example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp
...updated 40 targets...
</tt></pre>
<p>
If all is well, you should now have:</p>
<div class="itemizedlist"><ul type="disc">
<li>
libboost_python.so
</li>
boost_python.dll
</li>
<li>
hello.so
</li>
hello.pyd
</li>
</ul></div>
<p>
if you are on Unix.
</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>
<tt class="literal">boost_python.dll</tt> and <tt class="literal">hello.pyd</tt> can be
found somewhere in your project's <tt class="literal">bin</tt> directory. After a
successful build, you 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>
if you are on Unix.</p>
<p><tt class="literal">boost_python.dll</tt> can be found somewhere in <tt class="literal">libs\python\build\bin</tt>
while <tt class="literal">hello.pyd</tt> can be found somewhere in
<tt class="literal">libs\python\example\tutorial\bin</tt>. After a successful build, you can just
link in these DLLs with the Python interpreter. In Windows for example, you
can simply put these libraries inside the directory where the Python
executable is.</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>
<p>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<span class="bold"><b>There you go... Have fun!</b></span>
</p></blockquote></div>
You may now fire up Python and run our hello module:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> import</span><span class="identifier"> hello</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> 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></tt></pre>
<div class="blockquote"><blockquote class="blockquote"><p><span class="bold"><b>There you go... Have fun!</b></span></p></blockquote></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright © 2002-2005 Joel
de Guzman, David Abrahams</small></td>
<td align="right"><small>Copyright © 2002-2004 Joel de Guzman, David Abrahams</small></td>
</tr></table>
<hr>
<div class="spirit-nav">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -14,9 +11,9 @@
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td valign="top"><img alt="boost.png (6897 bytes)" 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="../../../../../../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>
@@ -29,172 +26,99 @@
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="python.iterators"></a>Iterators</h2></div></div></div>
<p>
In C++, and STL in particular, we see iterators everywhere. Python also has
iterators, but these are two very different beasts.
</p>
<p>
<span class="bold"><b>C++ iterators:</b></span>
</p>
In C++, and STL in particular, we see iterators everywhere. Python also has
iterators, but these are two very different beasts.</p>
<p><span class="bold"><b>C++ iterators:</b></span></p>
<div class="itemizedlist"><ul type="disc">
<li>
C++ has 5 type categories (random-access, bidirectional, forward, input,
output)
</li>
C++ has 5 type categories (random-access, bidirectional, forward, input, output)
</li>
<li>
There are 2 Operation categories: reposition, access
</li>
There are 2 Operation categories: reposition, access
</li>
<li>
A pair of iterators is needed to represent a (first/last) range.
</li>
A pair of iterators is needed to represent a (first/last) range.
</li>
</ul></div>
<p>
<span class="bold"><b>Python Iterators:</b></span>
</p>
<p><span class="bold"><b>Python Iterators:</b></span></p>
<div class="itemizedlist"><ul type="disc">
<li>
1 category (forward)
</li>
1 category (forward)
</li>
<li>
1 operation category (next())
</li>
1 operation category (next())
</li>
<li>
Raises StopIteration exception at end
</li>
Raises StopIteration exception at end
</li>
</ul></div>
<p>
The typical Python iteration protocol: <tt class="literal"><span class="bold"><b>for y
in x...</b></span></tt> is as follows:
</p>
The typical Python iteration protocol: <tt class="literal"><span class="bold"><b>for y in x...</b></span></tt> is as follows:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">iter</span><span class="special"> =</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span>         #<span class="identifier"> get</span><span class="identifier"> iterator</span><span class="keyword">
try</span><span class="special">:</span><span class="keyword">
while</span><span class="number"> 1</span><span class="special">:</span><span class="identifier">
y</span><span class="special"> =</span><span class="identifier"> iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">()</span>         #<span class="identifier"> get</span><span class="identifier"> each</span><span class="identifier"> item</span><span class="special">
...</span>                     #<span class="identifier"> process</span><span class="identifier"> y</span><span class="identifier">
except</span><span class="identifier"> StopIteration</span><span class="special">:</span><span class="identifier"> pass</span>  #<span class="identifier"> iterator</span><span class="identifier"> exhausted</span></tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator
</span><span class="keyword">try</span><span class="special">:</span>
<span class="keyword">while</span> <span class="number">1</span><span class="special">:</span>
<span class="identifier">y</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">()</span> <span class="comment"># get each item
</span> <span class="special">...</span> <span class="comment"># process y
</span><span class="keyword">except</span> <span class="identifier">StopIteration</span><span class="special">:</span> <span class="keyword">pass</span> <span class="comment"># iterator exhausted
</span></pre>
Boost.Python provides some mechanisms to make C++ iterators play along
nicely as Python iterators. What we need to do is to produce
appropriate <span class="underline">_iter</span>_ function from C++ iterators that is compatible
with the Python iteration protocol. For example:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">object</span><span class="identifier"> get_iterator</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><span class="identifier">
object</span><span class="identifier"> iter</span><span class="special"> =</span><span class="identifier"> get_iterator</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span><span class="identifier">
object</span><span class="identifier"> first</span><span class="special"> =</span><span class="identifier"> iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">();</span></tt></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 <tt class="computeroutput"><span class="identifier">__iter__</span></tt> function from C++ iterators that
is compatible with the Python iteration protocol. For example:
</p>
Or for use in class_&lt;&gt;:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p><span class="bold"><b>range</b></span></p>
<p>
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special">&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>
<span class="identifier">object</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">get_iterator</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
<span class="identifier">object</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">();</span>
</pre>
<p>
Or for use in class_&lt;&gt;:
</p>
<pre class="programlisting">
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special">&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"><b>range</b></span>
</p>
<p>
We can create a Python savvy iterator using the range function:
</p>
We can create a Python savvy iterator using the range function:</p>
<div class="itemizedlist"><ul type="disc">
<li>
range(start, finish)
</li>
range(start, finish)
</li>
<li>
range&lt;Policies,Target&gt;(start, finish)
</li>
range&lt;Policies,Target&gt;(start, finish)
</li>
</ul></div>
<p>
Here, start/finish may be one of:
</p>
Here, start/finish may be one of:</p>
<div class="itemizedlist"><ul type="disc">
<li>
member data pointers
</li>
member data pointers
</li>
<li>
member function pointers
</li>
member function pointers
</li>
<li>
adaptable function object (use Target parameter)
</li>
adaptable function object (use Target parameter)
</li>
</ul></div>
<p>
<span class="bold"><b>iterator</b></span>
</p>
<p><span class="bold"><b>iterator</b></span></p>
<div class="itemizedlist"><ul type="disc"><li>
iterator&lt;T, Policies&gt;()
</li></ul></div>
iterator&lt;T, Policies&gt;()
</li></ul></div>
<p>
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>
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
Particle accelerator code:
</p>
Let's put this into action... Here's an example from some hypothetical
bogon Particle accelerator code:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">f</span><span class="special"> =</span><span class="identifier"> Field</span><span class="special">()</span><span class="keyword">
for</span><span class="identifier"> x</span><span class="identifier"> in</span><span class="identifier"> f</span><span class="special">.</span><span class="identifier">pions</span><span class="special">:</span><span class="identifier">
smash</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span><span class="keyword">
for</span><span class="identifier"> y</span><span class="identifier"> in</span><span class="identifier"> f</span><span class="special">.</span><span class="identifier">bogons</span><span class="special">:</span><span class="identifier">
count</span><span class="special">(</span><span class="identifier">y</span><span class="special">)</span></tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
<span class="keyword">for</span> <span class="identifier">x</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">pions</span><span class="special">:</span>
<span class="identifier">smash</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
<span class="keyword">for</span> <span class="identifier">y</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">bogons</span><span class="special">:</span>
<span class="identifier">count</span><span class="special">(</span><span class="identifier">y</span><span class="special">)</span>
</pre>
<p>
Now, our C++ Wrapper:
</p>
<p>
</p>
<pre class="programlisting">
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="string">"Field"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"pions"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_begin</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_end</span><span class="special">))</span>
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"bogons"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&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"><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 <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>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">list_assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">o</span><span class="special">)</span> <span class="special">{</span>
<span class="comment">// Turn a Python sequence into an STL input range
</span> <span class="identifier">stl_input_iterator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">o</span><span class="special">),</span> <span class="identifier">end</span><span class="special">;</span>
<span class="identifier">l</span><span class="special">.</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">);</span>
<span class="special">}</span>
<span class="comment">// Part of the wrapper for list&lt;int&gt;
</span><span class="identifier">class_</span><span class="special">&lt;</span><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="special">&gt;(</span><span class="string">"list_int"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"assign"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">list_assign</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;)</span>
<span class="comment">// ...
</span> <span class="special">;</span>
</pre>
<p>
Now in Python, we can assign any integer sequence to <tt class="computeroutput"><span class="identifier">list_int</span></tt>
objects:
</p>
<p>
</p>
<pre class="programlisting">
<span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
<span class="identifier">x</span><span class="special">.</span><span class="identifier">assign</span><span class="special">([</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">,</span><span class="number">5</span><span class="special">])</span>
</pre>
Now, our C++ Wrapper:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="string">"Field"</span><span class="special">)</span><span class="special">
.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"pions"</span><span class="special">,</span><span class="identifier"> range</span><span class="special">(&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_begin</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_end</span><span class="special">))</span><span class="special">
.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"bogons"</span><span class="special">,</span><span class="identifier"> range</span><span class="special">(&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></tt></pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright © 2002-2005 Joel
de Guzman, David Abrahams</small></td>
<td align="right"><small>Copyright © 2002-2004 Joel de Guzman, David Abrahams</small></td>
</tr></table>
<hr>
<div class="spirit-nav">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -14,9 +11,9 @@
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td valign="top"><img alt="boost.png (6897 bytes)" 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="../../../../../../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>
@@ -35,307 +32,223 @@
<dt><span class="section"><a href="object.html#python.enums">Enums</a></span></dt>
</dl></div>
<p>
Python is dynamically typed, unlike C++ which is statically typed. Python variables
may hold an integer, a float, list, dict, tuple, str, long etc., among other
things. In the viewpoint of Boost.Python and C++, these Pythonic variables
are just instances of class <tt class="literal">object</tt>. We shall see in this
chapter how to deal with Python objects.
</p>
Python is dynamically typed, unlike C++ which is statically typed. Python
variables may hold an integer, a float, list, dict, tuple, str, long etc.,
among other things. In the viewpoint of Boost.Python and C++, these
Pythonic variables are just instances of class <tt class="literal">object</tt>. We shall see in
this chapter how to deal with Python objects.</p>
<p>
As mentioned, one of the goals of Boost.Python is to provide a bidirectional
mapping between C++ and Python while maintaining the Python feel. Boost.Python
C++ <tt class="literal">object</tt>s are as close as possible to Python. This should
minimize the learning curve significantly.
</p>
<p>
<span class="inlinemediaobject"><img src="../images/python.png" alt="python"></span>
</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++ <tt class="literal">object</tt>s are as close as possible to Python. This
should minimize the learning curve significantly.</p>
<p><span class="inlinemediaobject"><img src="../images/python.png"></span></p>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.basic_interface"></a>Basic Interface</h3></div></div></div>
<p>
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>
Class <tt class="literal">object</tt> wraps <tt class="literal">PyObject*</tt>. All the intricacies of dealing with
<tt class="literal">PyObject</tt>s such as managing reference counting are handled by the
<tt class="literal">object</tt> class. C++ object interoperability is seamless. Boost.Python C++
<tt class="literal">object</tt>s can in fact be explicitly constructed from any C++ object.</p>
<p>
To illustrate, this Python code snippet:
</p>
<p>
</p>
<pre class="programlisting">
<span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">):</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">'foo'</span><span class="special">):</span>
<span class="identifier">x</span><span class="special">[</span><span class="number">3</span><span class="special">:</span><span class="number">7</span><span class="special">]</span> <span class="special">=</span> <span class="string">'bar'</span>
<span class="keyword">else</span><span class="special">:</span>
<span class="identifier">x</span><span class="special">.</span><span class="identifier">items</span> <span class="special">+=</span> <span class="identifier">y</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="identifier">x</span><span class="special">)</span>
<span class="keyword">return</span> <span class="identifier">x</span>
To illustrate, this Python code snippet:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">def</span><span class="identifier"> f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier"> y</span><span class="special">):</span><span class="keyword">
if</span><span class="special"> (</span><span class="identifier">y</span><span class="special"> ==</span><span class="char"> 'foo'</span><span class="special">):</span><span class="identifier">
x</span><span class="special">[</span><span class="number">3</span><span class="special">:</span><span class="number">7</span><span class="special">]</span><span class="special"> =</span><span class="char"> 'bar'</span><span class="keyword">
else</span><span class="special">:</span><span class="identifier">
x</span><span class="special">.</span><span class="identifier">items</span><span class="special"> +=</span><span class="identifier"> y</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="identifier"> x</span><span class="special">)</span><span class="keyword">
return</span><span class="identifier"> x</span><span class="identifier">
<span class="keyword">def</span> <span class="identifier">getfunc</span><span class="special">():</span>
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">;</span>
</pre>
def</span><span class="identifier"> getfunc</span><span class="special">():</span><span class="keyword">
return</span><span class="identifier"> f</span><span class="special">;</span></tt></pre>
<p>
Can be rewritten in C++ using Boost.Python facilities this way:
</p>
Can be rewritten in C++ using Boost.Python facilities this way:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">object</span><span class="identifier"> f</span><span class="special">(</span><span class="identifier">object</span><span class="identifier"> x</span><span class="special">,</span><span class="identifier"> object</span><span class="identifier"> y</span><span class="special">)</span><span class="special"> {</span><span class="keyword">
if</span><span class="special"> (</span><span class="identifier">y</span><span class="special"> ==</span><span class="string"> "foo"</span><span class="special">)</span><span class="identifier">
x</span><span class="special">.</span><span class="identifier">slice</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="number">7</span><span class="special">)</span><span class="special"> =</span><span class="string"> "bar"</span><span class="special">;</span><span class="keyword">
else</span><span class="identifier">
x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"items"</span><span class="special">)</span><span class="special"> +=</span><span class="identifier"> y</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="identifier"> x</span><span class="special">);</span><span class="keyword">
return</span><span class="identifier"> x</span><span class="special">;</span><span class="special">
}</span><span class="identifier">
object</span><span class="identifier"> getfunc</span><span class="special">()</span><span class="special"> {</span><span class="keyword">
return</span><span class="identifier"> object</span><span class="special">(</span><span class="identifier">f</span><span class="special">);</span><span class="special">
}</span></tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">object</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">"foo"</span><span class="special">)</span>
<span class="identifier">x</span><span class="special">.</span><span class="identifier">slice</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="number">7</span><span class="special">)</span> <span class="special">=</span> <span class="string">"bar"</span><span class="special">;</span>
<span class="keyword">else</span>
<span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"items"</span><span class="special">)</span> <span class="special">+=</span> <span class="identifier">y</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">x</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">object</span> <span class="identifier">getfunc</span><span class="special">()</span> <span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">object</span><span class="special">(</span><span class="identifier">f</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
Apart from cosmetic differences due to the fact that we are writing the code
in C++, the look and feel should be immediately apparent to the Python coder.
</p>
Apart from cosmetic differences due to the fact that we are writing the
code in C++, the look and feel should be immediately apparent to the Python
coder.</p>
</div>
<div class="section" lang="en">
<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 <tt class="literal">object</tt> types
corresponding to that of Python's:
</p>
Boost.Python comes with a set of derived <tt class="literal">object</tt> types corresponding to
that of Python's:</p>
<div class="itemizedlist"><ul type="disc">
<li>
list
</li>
list
</li>
<li>
dict
</li>
dict
</li>
<li>
tuple
</li>
tuple
</li>
<li>
str
</li>
str
</li>
<li>
long_
</li>
long_
</li>
<li>
enum
</li>
enum
</li>
</ul></div>
<p>
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>
These derived <tt class="literal">object</tt> types act like real Python types. For instance:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
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>
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"><tt class="literal"><span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span></tt></pre>
<p><tt class="literal">make_tuple</tt> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>. Example:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
<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>
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 <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"><tt class="literal"><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><span class="special">
{</span><span class="identifier">
object</span><span class="identifier"> n2</span><span class="special"> =</span><span class="identifier"> name</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"upper"</span><span class="special">)();</span><span class="comment"> // NAME = name.upper()
</span><span class="identifier"> str</span><span class="identifier"> NAME</span><span class="special"> =</span><span class="identifier"> name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span><span class="comment"> // better
</span><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><span class="special">
}</span></tt></pre>
<p>
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
<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>
<span class="special">{</span>
<span class="identifier">object</span> <span class="identifier">n2</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"upper"</span><span class="special">)();</span> <span class="comment">// NAME = name.upper()
</span> <span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span> <span class="comment">// better
</span> <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>
<span class="special">}</span>
</pre>
In finer detail:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">str</span><span class="identifier"> NAME</span><span class="special"> =</span><span class="identifier"> name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span></tt></pre>
<p>
In finer detail:
</p>
<pre class="programlisting">
<span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span>
</pre>
Illustrates that we provide versions of the str type's methods as C++
member functions.</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
Illustrates that we provide versions of the str type's methods as C++ member
functions.
</p>
<pre class="programlisting">
<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>
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>
<p><span class="inlinemediaobject"><img src="../images/alert.png"></span><span class="bold"><b>Beware</b></span> the common pitfall of forgetting that the constructors
of most of Python's mutable types make copies, just as in Python.</p>
<p>
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>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>Beware</b></span> the common
pitfall of forgetting that the constructors of most of Python's mutable types
make copies, just as in Python.
</p>
Python:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> d</span><span class="special"> =</span><span class="identifier"> dict</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special">)</span>     #<span class="identifier"> copies</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> d</span><span class="special">[</span><span class="char">'whatever'</span><span class="special">]</span>            #<span class="identifier"> modifies</span><span class="identifier"> the</span><span class="identifier"> copy</span></tt></pre>
<p>
Python:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">dict</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special">)</span> <span class="comment"># copies x.__dict__
</span><span class="special">&gt;&gt;&gt;</span> <span class="identifier">d</span><span class="special">[</span><span class="string">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span> <span class="comment"># modifies the copy
</span></pre>
<p>
C++:
</p>
<pre class="programlisting">
<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>
C++:</p>
<pre class="programlisting"><tt class="literal"><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="identifier"> copies</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">__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="identifier"> modifies</span><span class="identifier"> the</span><span class="identifier"> copy</span></tt></pre>
<a name="derived_object_types.class__lt_t_gt__as_objects"></a><h2>
<a name="id461067"></a>
class_&lt;T&gt; as objects
</h2>
<a name="id459043"></a>class_&lt;T&gt; as objects</h2>
<p>
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>
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>
<p>
We can use this to create wrapped instances. Example:
</p>
<pre class="programlisting">
<span class="identifier">object</span> <span class="identifier">vec345</span> <span class="special">=</span> <span class="special">(</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&gt;(</span><span class="string">"Vec2"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;())</span>
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"length"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">length</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"angle"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">angle</span><span class="special">)</span>
<span class="special">)(</span><span class="number">3.0</span><span class="special">,</span> <span class="number">4.0</span><span class="special">);</span>
We can use this to create wrapped instances. Example:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">object</span><span class="identifier"> vec345</span><span class="special"> =</span><span class="special"> (</span><span class="identifier">
class_</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&gt;(</span><span class="string">"Vec2"</span><span class="special">,</span><span class="identifier"> init</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span><span class="keyword"> double</span><span class="special">&gt;())</span><span class="special">
.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"length"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">length</span><span class="special">)</span><span class="special">
.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"angle"</span><span class="special">,</span><span class="special"> &amp;</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">angle</span><span class="special">)</span><span class="special">
)(</span><span class="number">3.0</span><span class="special">,</span><span class="number"> 4.0</span><span class="special">);</span><span class="identifier">
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">vec345</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="special">==</span> <span class="number">5.0</span><span class="special">);</span>
</pre>
assert</span><span class="special">(</span><span class="identifier">vec345</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="special"> ==</span><span class="number"> 5.0</span><span class="special">);</span></tt></pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<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 <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>
At some point, we will need to get C++ values out of object instances. This
can be achieved with the <tt class="literal">extract&lt;T&gt;</tt> function. Consider the following:</p>
<pre class="programlisting"><tt class="literal"><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></tt></pre>
<p>
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">
<span class="keyword">double</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</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="identifier">Vec2</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&amp;&gt;(</span><span class="identifier">o</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">l</span> <span class="special">==</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">length</span><span class="special">());</span>
</pre>
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"><tt class="literal"><span class="keyword">double</span><span class="identifier"> l</span><span class="special"> =</span><span class="identifier"> extract</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</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="identifier">
Vec2</span><span class="special">&amp;</span><span class="identifier"> v</span><span class="special"> =</span><span class="identifier"> extract</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&amp;&gt;(</span><span class="identifier">o</span><span class="special">);</span><span class="identifier">
assert</span><span class="special">(</span><span class="identifier">l</span><span class="special"> ==</span><span class="identifier"> v</span><span class="special">.</span><span class="identifier">length</span><span class="special">());</span></tt></pre>
<p>
The first line attempts to extract the "length" attribute of the
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>
The first line attempts to extract the "length" attribute of the
Boost.Python <tt class="literal">object</tt><tt class="literal">o</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><tt class="literal">o</tt>.</p>
<p>
Take note that we said "attempt to" above. What if the Boost.Python
<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
<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>
<pre class="programlisting">
<span class="identifier">extract</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&amp;&gt;</span> <span class="identifier">x</span><span class="special">(</span><span class="identifier">o</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">check</span><span class="special">())</span> <span class="special">{</span>
<span class="identifier">Vec2</span><span class="special">&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 <tt class="literal">extract&lt;T&gt;</tt>
facility in fact solves the mutable copying problem:
</p>
<pre class="programlisting">
<span class="identifier">dict</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="identifier">dict</span><span class="special">&gt;(</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="identifier">d</span><span class="special">[</span><span class="string">"whatever"</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies x.__dict__ !
</span></pre>
Take note that we said "attempt to" above. What if the Boost.Python
<tt class="literal">object</tt><tt class="literal">o</tt> does not really hold a <tt class="literal">Vec2</tt> type? This is certainly
a possibility considering the dynamic nature of Python <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>
<pre class="programlisting"><tt class="literal"><span class="identifier">extract</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&amp;&gt;</span><span class="identifier"> x</span><span class="special">(</span><span class="identifier">o</span><span class="special">);</span><span class="keyword">
if</span><span class="special"> (</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">check</span><span class="special">())</span><span class="special"> {</span><span class="identifier">
Vec2</span><span class="special">&amp;</span><span class="identifier"> v</span><span class="special"> =</span><span class="identifier"> x</span><span class="special">();</span><span class="special"> ...</span></tt></pre>
<p><span class="inlinemediaobject"><img src="../images/tip.png"></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"><tt class="literal"><span class="identifier">dict</span><span class="identifier"> d</span><span class="special"> =</span><span class="identifier"> extract</span><span class="special">&lt;</span><span class="identifier">dict</span><span class="special">&gt;(</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="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="identifier"> modifies</span><span class="identifier"> x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special"> !</span></tt></pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<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 <tt class="literal">enum</tt> type, we'll often want to expose our C++ enums
to Python as an <tt class="literal">int</tt>. Boost.Python's enum facility makes
this easy while taking care of the proper conversions from Python's dynamic
typing to C++'s strong static typing (in C++, ints cannot be implicitly converted
to enums). To illustrate, given a C++ enum:
</p>
<pre class="programlisting">
<span class="keyword">enum</span> <span class="identifier">choice</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
</pre>
Boost.Python has a nifty facility to capture and wrap C++ enums. While
Python has no <tt class="literal">enum</tt> type, we'll often want to expose our C++ enums to
Python as an <tt class="literal">int</tt>. Boost.Python's enum facility makes this easy while
taking care of the proper conversions from Python's dynamic typing to C++'s
strong static typing (in C++, ints cannot be implicitly converted to
enums). To illustrate, given a C++ enum:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">enum</span><span class="identifier"> choice</span><span class="special"> {</span><span class="identifier"> red</span><span class="special">,</span><span class="identifier"> blue</span><span class="special"> };</span></tt></pre>
<p>
the construct:
</p>
<pre class="programlisting">
<span class="identifier">enum_</span><span class="special">&lt;</span><span class="identifier">choice</span><span class="special">&gt;(</span><span class="string">"choice"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</span><span class="special">,</span> <span class="identifier">red</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"blue"</span><span class="special">,</span> <span class="identifier">blue</span><span class="special">)</span>
<span class="special">;</span>
</pre>
the construct:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">enum_</span><span class="special">&lt;</span><span class="identifier">choice</span><span class="special">&gt;(</span><span class="string">"choice"</span><span class="special">)</span><span class="special">
.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</span><span class="special">,</span><span class="identifier"> red</span><span class="special">)</span><span class="special">
.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"blue"</span><span class="special">,</span><span class="identifier"> blue</span><span class="special">)</span><span class="special">
;</span></tt></pre>
<p>
can be used to expose to Python. The new enum type is created in the current
<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>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>what is a scope?</b></span><br>
<br> The scope is a class that has an associated global Python object which
controls the Python namespace in which new extension classes and wrapped
functions will be defined as attributes. Details can be found <a href="../../../../v2/scope.html" target="_top">here</a>.
</p>
can be used to expose to Python. The new enum type is created in the
current <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="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/note.png"></span><span class="bold"><b>what is a scope?</b></span><p></p>
<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>.</td></tr></tbody>
</table></div>
<p>
You can access those values in Python as
</p>
You can access those values in Python as</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span><span class="identifier">
my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span></tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
<span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
</pre>
<p>
where my_module is the module where the enum is declared. You can also create
a new scope around a class:
</p>
<p>
</p>
<pre class="programlisting">
<span class="identifier">scope</span> <span class="identifier">in_X</span> <span class="special">=</span> <span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">&gt;(</span><span class="string">"X"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
<span class="special">;</span>
where my_module is the module where the enum is declared. You can also
create a new scope around a class:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">scope</span><span class="identifier"> in_X</span><span class="special"> =</span><span class="identifier"> class_</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">&gt;(</span><span class="string">"X"</span><span class="special">)</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="special"> ...</span><span class="special"> )</span><span class="special">
.</span><span class="identifier">def</span><span class="special">(</span><span class="special"> ...</span><span class="special"> )</span><span class="special">
;</span><span class="comment">
<span class="comment">// Expose X::nested as X.nested
</span><span class="identifier">enum_</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">nested</span><span class="special">&gt;(</span><span class="string">"nested"</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</span><span class="special">,</span> <span class="identifier">red</span><span class="special">)</span>
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"blue"</span><span class="special">,</span> <span class="identifier">blue</span><span class="special">)</span>
<span class="special">;</span>
</pre>
// Expose X::nested as X.nested
</span><span class="identifier">enum_</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">nested</span><span class="special">&gt;(</span><span class="string">"nested"</span><span class="special">)</span><span class="special">
.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</span><span class="special">,</span><span class="identifier"> red</span><span class="special">)</span><span class="special">
.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"blue"</span><span class="special">,</span><span class="identifier"> blue</span><span class="special">)</span><span class="special">
;</span></tt></pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright © 2002-2005 Joel
de Guzman, David Abrahams</small></td>
<td align="right"><small>Copyright © 2002-2004 Joel de Guzman, David Abrahams</small></td>
</tr></table>
<hr>
<div class="spirit-nav">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -13,9 +10,9 @@
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%">
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
<td valign="top"><img alt="boost.png (6897 bytes)" 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="../../../../../../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>
@@ -33,417 +30,328 @@
<dt><span class="section"><a href="techniques.html#python.reducing_compiling_time">Reducing Compiling Time</a></span></dt>
</dl></div>
<p>
Here are presented some useful techniques that you can use while wrapping code
with Boost.Python.
</p>
Here are presented some useful techniques that you can use while wrapping code with Boost.Python.</p>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.creating_packages"></a>Creating Packages</h3></div></div></div>
<p>
A Python package is a collection of modules that provide to the user a certain
functionality. If you're not familiar on how to create packages, a good introduction
to them is provided in the <a href="http://www.python.org/doc/current/tut/node8.html" target="_top">Python
Tutorial</a>.
</p>
A Python package is a collection of modules that provide to the user a certain
functionality. If you're not familiar on how to create packages, a good
introduction to them is provided in the
<a href="http://www.python.org/doc/current/tut/node8.html" target="_top">Python Tutorial</a>.</p>
<p>
But we are wrapping C++ code, using Boost.Python. How can we provide a nice
package interface to our users? To better explain some concepts, let's work
with an example.
</p>
But we are wrapping C++ code, using Boost.Python. How can we provide a nice
package interface to our users? To better explain some concepts, let's work
with an example.</p>
<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)
<tt class="literal">sounds</tt>. Our library already has a neat C++ namespace hierarchy,
like so:
</p>
<pre class="programlisting">
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span>
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">io</span>
<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">filters</span>
</pre>
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)
<tt class="literal">sounds</tt>. Our library already has a neat C++ namespace hierarchy, like so:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span><span class="identifier">
sounds</span><span class="special">::</span><span class="identifier">io</span><span class="identifier">
sounds</span><span class="special">::</span><span class="identifier">filters</span></tt></pre>
<p>
We would like to present this same hierarchy to the Python user, allowing
him to write code like this:
</p>
<pre class="programlisting">
<span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
<span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span> <span class="comment"># echo is a C++ function
</span></pre>
We would like to present this same hierarchy to the Python user, allowing him
to write code like this:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">import</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="identifier">
sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span> #<span class="identifier"> echo</span><span class="identifier"> is</span><span class="identifier"> a</span><span class="identifier"> C</span><span class="special">++</span><span class="identifier"> function</span></tt></pre>
<p>
The first step is to write the wrapping code. We have to export each module
separately with Boost.Python, like this:
</p>
<pre class="programlisting">
<span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">core</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">core</span><span class="special">)</span>
<span class="special">{</span>
<span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span> <span class="identifier">namespace</span> <span class="special">*/</span>
<span class="special">...</span>
<span class="special">}</span>
The first step is to write the wrapping code. We have to export each module
separately with Boost.Python, like this:</p>
<pre class="programlisting"><tt class="literal"><span class="comment">/* file core.cpp */</span><span class="identifier">
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">core</span><span class="special">)</span><span class="special">
{</span><span class="comment">
/* export everything in the sounds::core namespace */</span><span class="special">
...</span><span class="special">
}</span><span class="comment">
<span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">io</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">io</span><span class="special">)</span>
<span class="special">{</span>
<span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">io</span> <span class="identifier">namespace</span> <span class="special">*/</span>
<span class="special">...</span>
<span class="special">}</span>
/* file io.cpp */</span><span class="identifier">
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">io</span><span class="special">)</span><span class="special">
{</span><span class="comment">
/* export everything in the sounds::io namespace */</span><span class="special">
...</span><span class="special">
}</span><span class="comment">
<span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">filters</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">filters</span><span class="special">)</span>
<span class="special">{</span>
<span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">filters</span> <span class="identifier">namespace</span> <span class="special">*/</span>
<span class="special">...</span>
<span class="special">}</span>
</pre>
/* file filters.cpp */</span><span class="identifier">
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">filters</span><span class="special">)</span><span class="special">
{</span><span class="comment">
/* export everything in the sounds::filters namespace */</span><span class="special">
...</span><span class="special">
}</span></tt></pre>
<p>
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>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> The extension <tt class="literal">.pyd</tt> is used for python
extension modules, which are just shared libraries. Using the default for
your system, like <tt class="literal">.so</tt> for Unix and <tt class="literal">.dll</tt>
for Windows, works just as well.
</p>
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="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/note.png"></span> The extension <tt class="literal">.pyd</tt> is used for python extension modules, which
are just shared libraries. Using the default for your system, like <tt class="literal">.so</tt> for
Unix and <tt class="literal">.dll</tt> for Windows, works just as well.</td></tr></tbody>
</table></div>
<p>
Now, we create this directory structure for our Python package:
</p>
<pre class="programlisting">sounds/
__init__.py
core.pyd
filters.pyd
io.pyd
</pre>
Now, we create this directory structure for our Python package:</p>
<pre class="programlisting"><tt class="literal"> sounds/
<span class="underline">_init</span>_.py
core.pyd
filters.pyd
io.pyd
</tt></pre>
<p>
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>
The file <tt class="literal"><span class="underline">_init</span>_.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 <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>
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>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> import</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">io</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> import</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> sound</span><span class="special"> =</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">io</span><span class="special">.</span><span class="identifier">open</span><span class="special">(</span><span class="char">'file.mp3'</span><span class="special">)</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> new_sound</span><span class="special"> =</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">,</span><span class="number"> 1.0</span><span class="special">)</span></tt></pre>
<p>
</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">io</span>
<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>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">sound</span> <span class="special">=</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span><span class="special">.</span><span class="identifier">open</span><span class="special">(</span><span class="string">'file.mp3'</span><span class="special">)</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">new_sound</span> <span class="special">=</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">,</span> <span class="number">1.0</span><span class="special">)</span>
</pre>
Nice heh?</p>
<p>
Nice heh?
</p>
This is the simplest way to create hierarchies of packages, but it is not very
flexible. What if we want to add a <span class="emphasis"><em>pure</em></span> Python function to the filters
package, for instance, one that applies 3 filters in a sound object at once?
Sure, you can do this in C++ and export it, but why not do so in Python? You
don't have to recompile the extension modules, plus it will be easier to write
it.</p>
<p>
This is the simplest way to create hierarchies of packages, but it is not
very flexible. What if we want to add a <span class="emphasis"><em>pure</em></span> Python
function to the filters package, for instance, one that applies 3 filters
in a sound object at once? Sure, you can do this in C++ and export it, but
why not do so in Python? You don't have to recompile the extension modules,
plus it will be easier to write it.
</p>
If we want this flexibility, we will have to complicate our package hierarchy a
little. First, we will have to change the name of the extension modules:</p>
<pre class="programlisting"><tt class="literal"><span class="comment">/* file core.cpp */</span><span class="identifier">
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_core</span><span class="special">)</span><span class="special">
{</span><span class="special">
...</span><span class="comment">
/* export everything in the sounds::core namespace */</span><span class="special">
}</span></tt></pre>
<p>
If we want this flexibility, we will have to complicate our package hierarchy
a little. First, we will have to change the name of the extension modules:
</p>
Note that we added an underscore to the module name. The filename will have 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>
<pre class="programlisting"><tt class="literal"> sounds/
<span class="underline">_init</span>_.py
core/
<span class="underline">_init</span>_.py
_core.pyd
filters/
<span class="underline">_init</span>_.py
_filters.pyd
io/
<span class="underline">_init</span>_.py
_io.pyd
</tt></pre>
<p>
</p>
<pre class="programlisting">
<span class="comment">/* file core.cpp */</span>
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_core</span><span class="special">)</span>
<span class="special">{</span>
<span class="special">...</span>
<span class="comment">/* export everything in the sounds::core namespace */</span>
<span class="special">}</span>
</pre>
Note that we created a directory for each extension module, and added a
<span class="underline">_init</span>_.py to each one. But if we leave it that way, the user will have to
access the functions in the core module with this syntax:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> import</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span><span class="special">
&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></tt></pre>
<p>
Note that we added an underscore to the module name. The filename will have
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>
<pre class="programlisting">sounds/
__init__.py
core/
__init__.py
_core.pyd
filters/
__init__.py
_filters.pyd
io/
__init__.py
_io.pyd
</pre>
which is not what we want. But here enters the <tt class="literal"><span class="underline">_init</span>_.py</tt> magic: everything
that is brought to the <tt class="literal"><span class="underline">_init</span>_.py</tt> namespace can be accessed directly by the
user. So, all we have to do is bring the entire namespace from <tt class="literal">_core.pyd</tt>
to <tt class="literal">core/<span class="underline">_init</span><span class="underline">.py]. So add this line of code to [^sounds/core/</span><span class="underline">init</span>_.py</tt>:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">from</span><span class="identifier"> _core</span><span class="identifier"> import</span><span class="special"> *</span></tt></pre>
<p>
Note that we created a directory for each extension module, and added a __init__.py
to each one. But if we leave it that way, the user will have to access the
functions in the core module with this syntax:
</p>
We do the same for the other packages. Now the user accesses the functions and
classes in the extension modules like before:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> import</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span></tt></pre>
<p>
</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">core</span><span class="special">.</span><span class="identifier">_core</span>
<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>
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,
<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"><tt class="literal"><span class="identifier">import</span><span class="identifier"> _filters</span><span class="identifier">
def</span><span class="identifier"> echo_noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">):</span><span class="identifier">
s</span><span class="special"> =</span><span class="identifier"> _filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span><span class="identifier">
s</span><span class="special"> =</span><span class="identifier"> _filters</span><span class="special">.</span><span class="identifier">noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span><span class="keyword">
return</span><span class="identifier"> s</span></tt></pre>
<p>
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 <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>
</pre>
Next, we add this line to <tt class="literal">sounds<span class="emphasis"><em>filters</em></span><span class="underline">_init</span>_.py</tt>:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">from</span><span class="identifier"> echo_noise</span><span class="identifier"> import</span><span class="identifier"> echo_noise</span></tt></pre>
<p>
We do the same for the other packages. Now the user accesses the functions
and classes in the extension modules like before:
</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>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span>
</pre>
<p>
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, <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">
<span class="keyword">import</span> <span class="identifier">_filters</span>
<span class="keyword">def</span> <span class="identifier">echo_noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">):</span>
<span class="identifier">s</span> <span class="special">=</span> <span class="identifier">_filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span>
<span class="identifier">s</span> <span class="special">=</span> <span class="identifier">_filters</span><span class="special">.</span><span class="identifier">noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span>
<span class="keyword">return</span> <span class="identifier">s</span>
</pre>
<p>
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 <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>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo_noise</span><span class="special">(...)</span>
</pre>
And that's it. The user now accesses this function like any other function
from the <tt class="literal">filters</tt> package:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> import</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo_noise</span><span class="special">(...)</span></tt></pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.extending_wrapped_objects_in_python"></a>Extending Wrapped Objects in Python</h3></div></div></div>
<p>
Thanks to Python's flexibility, you can easily add new methods to a class,
even after it was already created:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">class</span> <span class="identifier">C</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span> <span class="keyword">pass</span>
<span class="special">&gt;&gt;&gt;</span>
<span class="special">&gt;&gt;&gt;</span> <span class="comment"># a regular function
</span><span class="special">&gt;&gt;&gt;</span> <span class="keyword">def</span> <span class="identifier">C_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span> <span class="keyword">return</span> <span class="string">'A C instance!'</span>
<span class="special">&gt;&gt;&gt;</span>
<span class="special">&gt;&gt;&gt;</span> <span class="comment"># now we turn it in a member function
</span><span class="special">&gt;&gt;&gt;</span> <span class="identifier">C</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">C_str</span>
<span class="special">&gt;&gt;&gt;</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">C</span><span class="special">()</span>
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">c</span>
<span class="identifier">A</span> <span class="identifier">C</span> <span class="identifier">instance</span><span class="special">!</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">C_str</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span>
<span class="identifier">A</span> <span class="identifier">C</span> <span class="identifier">instance</span><span class="special">!</span>
</pre>
Thanks to Python's flexibility, you can easily add new methods to a class,
even after it was already created:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="keyword"> class</span><span class="identifier"> C</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span><span class="identifier"> pass</span><span class="special">
&gt;&gt;&gt;</span><span class="special">
&gt;&gt;&gt;</span> #<span class="identifier"> a</span><span class="identifier"> regular</span><span class="identifier"> function</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> def</span><span class="identifier"> C_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span><span class="keyword"> return</span><span class="char"> 'A C instance!'</span><span class="special">
&gt;&gt;&gt;</span><span class="special">
&gt;&gt;&gt;</span> #<span class="identifier"> now</span><span class="identifier"> we</span><span class="identifier"> turn</span><span class="identifier"> it</span><span class="identifier"> in</span><span class="identifier"> a</span><span class="identifier"> member</span><span class="identifier"> function</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> C</span><span class="special">.</span><span class="identifier">__str__</span><span class="special"> =</span><span class="identifier"> C_str</span><span class="special">
&gt;&gt;&gt;</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> c</span><span class="special"> =</span><span class="identifier"> C</span><span class="special">()</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> print</span><span class="identifier"> c</span><span class="identifier">
A</span><span class="identifier"> C</span><span class="identifier"> instance</span><span class="special">!</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> C_str</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span><span class="identifier">
A</span><span class="identifier"> C</span><span class="identifier"> instance</span><span class="special">!</span></tt></pre>
<p>
Yes, Python rox. <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
</p>
Yes, Python rox. <span class="inlinemediaobject"><img src="../images/smiley.png"></span></p>
<p>
We can do the same with classes that were wrapped with Boost.Python. Suppose
we have a class <tt class="literal">point</tt> in C++:
</p>
<p>
</p>
<pre class="programlisting">
<span class="keyword">class</span> <span class="identifier">point</span> <span class="special">{...};</span>
We can do the same with classes that were wrapped with Boost.Python. Suppose
we have a class <tt class="literal">point</tt> in C++:</p>
<pre class="programlisting"><tt class="literal"><span class="keyword">class</span><span class="identifier"> point</span><span class="special"> {...};</span><span class="identifier">
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">&gt;(</span><span class="string">"point"</span><span class="special">)...;</span>
<span class="special">}</span>
</pre>
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span><span class="special">
{</span><span class="identifier">
class_</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">&gt;(</span><span class="string">"point"</span><span class="special">)...;</span><span class="special">
}</span></tt></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 <tt class="literal">geom/__init__.py</tt>:
</p>
<p>
</p>
<pre class="programlisting">
<span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
If we are using the technique from the previous session,
<a href="techniques.html#python.creating_packages" title="Creating Packages">Creating Packages</a>, we can code directly
into <tt class="literal">geom/<span class="underline">_init</span>_.py</tt>:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">from</span><span class="identifier"> _geom</span><span class="identifier"> import</span><span class="special"> *</span>
<span class="comment"># a regular function
</span><span class="keyword">def</span> <span class="identifier">point_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
<span class="keyword">return</span> <span class="identifier">str</span><span class="special">((</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">self</span><span class="special">.</span><span class="identifier">y</span><span class="special">))</span>
#<span class="identifier"> a</span><span class="identifier"> regular</span><span class="identifier"> function</span><span class="identifier">
def</span><span class="identifier"> point_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span><span class="keyword">
return</span><span class="identifier"> str</span><span class="special">((</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">x</span><span class="special">,</span><span class="identifier"> self</span><span class="special">.</span><span class="identifier">y</span><span class="special">))</span>
<span class="comment"># now we turn it into a member function
</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">point_str</span>
</pre>
<p>
<span class="bold"><b>All</b></span> point instances created from C++ will
also have this member function! This technique has several advantages:
</p>
#<span class="identifier"> now</span><span class="identifier"> we</span><span class="identifier"> turn</span><span class="identifier"> it</span><span class="identifier"> into</span><span class="identifier"> a</span><span class="identifier"> member</span><span class="identifier"> function</span><span class="identifier">
point</span><span class="special">.</span><span class="identifier">__str__</span><span class="special"> =</span><span class="identifier"> point_str</span></tt></pre>
<p><span class="bold"><b>All</b></span> point instances created from C++ will also have this member function!
This technique has several advantages:</p>
<div class="itemizedlist"><ul type="disc">
<li>
Cut down compile times to zero for these additional functions
</li>
Cut down compile times to zero for these additional functions
</li>
<li>
Reduce the memory footprint to virtually zero
</li>
Reduce the memory footprint to virtually zero
</li>
<li>
Minimize the need to recompile
</li>
Minimize the need to recompile
</li>
<li>
Rapid prototyping (you can move the code to C++ if required without changing
the interface)
</li>
Rapid prototyping (you can move the code to C++ if required without changing the interface)
</li>
</ul></div>
<p>
You can even add a little syntactic sugar with the use of metaclasses. Let's
create a special metaclass that "injects" methods in other classes.
</p>
<pre class="programlisting">
<span class="comment"># The one Boost.Python uses for all wrapped classes.
</span><span class="comment"># You can use here any class exported by Boost instead of "point"
</span><span class="identifier">BoostPythonMetaclass</span> <span class="special">=</span> <span class="identifier">point</span><span class="special">.</span><span class="identifier">__class__</span>
You can even add a little syntactic sugar with the use of metaclasses. Let's
create a special metaclass that "injects" methods in other classes.</p>
<pre class="programlisting"><tt class="literal">
#<span class="identifier"> The</span><span class="identifier"> one</span><span class="identifier"> Boost</span><span class="special">.</span><span class="identifier">Python</span><span class="identifier"> uses</span><span class="keyword"> for</span><span class="identifier"> all</span><span class="identifier"> wrapped</span><span class="identifier"> classes</span><span class="special">.</span>
#<span class="identifier"> You</span><span class="identifier"> can</span><span class="identifier"> use</span><span class="identifier"> here</span><span class="identifier"> any</span><span class="keyword"> class</span><span class="identifier"> exported</span><span class="identifier"> by</span><span class="identifier"> Boost</span><span class="identifier"> instead</span><span class="identifier"> of</span><span class="string"> "point"</span><span class="identifier">
BoostPythonMetaclass</span><span class="special"> =</span><span class="identifier"> point</span><span class="special">.</span><span class="identifier">__class__</span><span class="keyword">
<span class="keyword">class</span> <span class="identifier">injector</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span>
<span class="keyword">class</span> <span class="identifier">__metaclass__</span><span class="special">(</span><span class="identifier">BoostPythonMetaclass</span><span class="special">):</span>
<span class="keyword">def</span> <span class="identifier">__init__</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">,</span> <span class="identifier">dict</span><span class="special">):</span>
<span class="keyword">for</span> <span class="identifier">b</span> <span class="keyword">in</span> <span class="identifier">bases</span><span class="special">:</span>
<span class="keyword">if</span> <span class="identifier">type</span><span class="special">(</span><span class="identifier">b</span><span class="special">)</span> <span class="keyword">not</span> <span class="keyword">in</span> <span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">type</span><span class="special">):</span>
<span class="keyword">for</span> <span class="identifier">k</span><span class="special">,</span><span class="identifier">v</span> <span class="keyword">in</span> <span class="identifier">dict</span><span class="special">.</span><span class="identifier">items</span><span class="special">():</span>
<span class="identifier">setattr</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">k</span><span class="special">,</span><span class="identifier">v</span><span class="special">)</span>
<span class="keyword">return</span> <span class="identifier">type</span><span class="special">.</span><span class="identifier">__init__</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">,</span> <span class="identifier">dict</span><span class="special">)</span>
class</span><span class="identifier"> injector</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span><span class="keyword">
class</span><span class="identifier"> __metaclass__</span><span class="special">(</span><span class="identifier">BoostPythonMetaclass</span><span class="special">):</span><span class="identifier">
def</span><span class="identifier"> __init__</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span><span class="identifier"> name</span><span class="special">,</span><span class="identifier"> bases</span><span class="special">,</span><span class="identifier"> dict</span><span class="special">):</span><span class="keyword">
for</span><span class="identifier"> b</span><span class="identifier"> in</span><span class="identifier"> bases</span><span class="special">:</span><span class="keyword">
if</span><span class="identifier"> type</span><span class="special">(</span><span class="identifier">b</span><span class="special">)</span><span class="keyword"> not</span><span class="identifier"> in</span><span class="special"> (</span><span class="identifier">self</span><span class="special">,</span><span class="identifier"> type</span><span class="special">):</span><span class="keyword">
for</span><span class="identifier"> k</span><span class="special">,</span><span class="identifier">v</span><span class="identifier"> in</span><span class="identifier"> dict</span><span class="special">.</span><span class="identifier">items</span><span class="special">():</span><span class="identifier">
setattr</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">k</span><span class="special">,</span><span class="identifier">v</span><span class="special">)</span><span class="keyword">
return</span><span class="identifier"> type</span><span class="special">.</span><span class="identifier">__init__</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span><span class="identifier"> name</span><span class="special">,</span><span class="identifier"> bases</span><span class="special">,</span><span class="identifier"> dict</span><span class="special">)</span>
<span class="comment"># inject some methods in the point foo
</span><span class="keyword">class</span> <span class="identifier">more_point</span><span class="special">(</span><span class="identifier">injector</span><span class="special">,</span> <span class="identifier">point</span><span class="special">):</span>
<span class="keyword">def</span> <span class="identifier">__repr__</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
<span class="keyword">return</span> <span class="string">'Point(x=%s, y=%s)'</span> <span class="special">%</span> <span class="special">(</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">self</span><span class="special">.</span><span class="identifier">y</span><span class="special">)</span>
<span class="keyword">def</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
<span class="keyword">print</span> <span class="string">'foo!'</span>
</pre>
#<span class="identifier"> inject</span><span class="identifier"> some</span><span class="identifier"> methods</span><span class="identifier"> in</span><span class="identifier"> the</span><span class="identifier"> point</span><span class="identifier"> foo</span><span class="keyword">
class</span><span class="identifier"> more_point</span><span class="special">(</span><span class="identifier">injector</span><span class="special">,</span><span class="identifier"> point</span><span class="special">):</span><span class="identifier">
def</span><span class="identifier"> __repr__</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span><span class="keyword">
return</span><span class="char"> 'Point(x=%s, y=%s)'</span><span class="special"> %</span><span class="special"> (</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">x</span><span class="special">,</span><span class="identifier"> self</span><span class="special">.</span><span class="identifier">y</span><span class="special">)</span><span class="identifier">
def</span><span class="identifier"> foo</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span><span class="identifier">
print</span><span class="char"> 'foo!'</span></tt></pre>
<p>
Now let's see how it got:
</p>
<pre class="programlisting">
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">point</span><span class="special">()</span>
<span class="identifier">Point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">10</span><span class="special">,</span> <span class="identifier">y</span><span class="special">=</span><span class="number">10</span><span class="special">)</span>
<span class="special">&gt;&gt;&gt;</span> <span class="identifier">point</span><span class="special">().</span><span class="identifier">foo</span><span class="special">()</span>
<span class="identifier">foo</span><span class="special">!</span>
</pre>
Now let's see how it got:</p>
<pre class="programlisting"><tt class="literal"><span class="special">&gt;&gt;&gt;</span><span class="identifier"> print</span><span class="identifier"> point</span><span class="special">()</span><span class="identifier">
Point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">10</span><span class="special">,</span><span class="identifier"> y</span><span class="special">=</span><span class="number">10</span><span class="special">)</span><span class="special">
&gt;&gt;&gt;</span><span class="identifier"> point</span><span class="special">().</span><span class="identifier">foo</span><span class="special">()</span><span class="identifier">
foo</span><span class="special">!</span></tt></pre>
<p>
Another useful idea is to replace constructors with factory functions:
</p>
<pre class="programlisting">
<span class="identifier">_point</span> <span class="special">=</span> <span class="identifier">point</span>
Another useful idea is to replace constructors with factory functions:</p>
<pre class="programlisting"><tt class="literal"><span class="identifier">_point</span><span class="special"> =</span><span class="identifier"> point</span><span class="identifier">
<span class="keyword">def</span> <span class="identifier">point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">0</span><span class="special">,</span> <span class="identifier">y</span><span class="special">=</span><span class="number">0</span><span class="special">):</span>
<span class="keyword">return</span> <span class="identifier">_point</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">)</span>
</pre>
def</span><span class="identifier"> point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">0</span><span class="special">,</span><span class="identifier"> y</span><span class="special">=</span><span class="number">0</span><span class="special">):</span><span class="keyword">
return</span><span class="identifier"> _point</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier"> y</span><span class="special">)</span></tt></pre>
<p>
In this simple case there is not much gained, but for constructurs with many
overloads and/or arguments this is often a great simplification, again with
virtually zero memory footprint and zero compile-time overhead for the keyword
support.
</p>
In this simple case there is not much gained, but for constructurs with
many overloads and/or arguments this is often a great simplification, again
with virtually zero memory footprint and zero compile-time overhead for
the keyword support.</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="python.reducing_compiling_time"></a>Reducing Compiling Time</h3></div></div></div>
<p>
If you have ever exported a lot of classes, you know that it takes quite
a good time to compile the Boost.Python wrappers. Plus the memory consumption
can easily become too high. If this is causing you problems, you can split
the class_ definitions in multiple files:
</p>
<p>
</p>
<pre class="programlisting">
<span class="comment">/* file point.cpp */</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>
<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>
If you have ever exported a lot of classes, you know that it takes quite a good
time to compile the Boost.Python wrappers. Plus the memory consumption can
easily become too high. If this is causing you problems, you can split the
class_ definitions in multiple files:</p>
<pre class="programlisting"><tt class="literal"><span class="comment">/* file point.cpp */</span><span class="preprocessor">
#include</span><span class="special"> &lt;</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span><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">
<span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">&gt;(</span><span class="string">"point"</span><span class="special">)...;</span>
<span class="special">}</span>
void</span><span class="identifier"> export_point</span><span class="special">()</span><span class="special">
{</span><span class="identifier">
class_</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">&gt;(</span><span class="string">"point"</span><span class="special">)...;</span><span class="special">
}</span><span class="comment">
<span class="comment">/* file triangle.cpp */</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">triangle</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>
<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>
/* file triangle.cpp */</span><span class="preprocessor">
#include</span><span class="special"> &lt;</span><span class="identifier">triangle</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span><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">
<span class="keyword">void</span> <span class="identifier">export_triangle</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">triangle</span><span class="special">&gt;(</span><span class="string">"triangle"</span><span class="special">)...;</span>
<span class="special">}</span>
</pre>
void</span><span class="identifier"> export_triangle</span><span class="special">()</span><span class="special">
{</span><span class="identifier">
class_</span><span class="special">&lt;</span><span class="identifier">triangle</span><span class="special">&gt;(</span><span class="string">"triangle"</span><span class="special">)...;</span><span class="special">
}</span></tt></pre>
<p>
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">
<span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">();</span>
<span class="keyword">void</span> <span class="identifier">export_triangle</span><span class="special">();</span>
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"><tt class="literal"><span class="keyword">void</span><span class="identifier"> export_point</span><span class="special">();</span><span class="keyword">
void</span><span class="identifier"> export_triangle</span><span class="special">();</span><span class="identifier">
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">export_point</span><span class="special">();</span>
<span class="identifier">export_triangle</span><span class="special">();</span>
<span class="special">}</span>
</pre>
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span><span class="special">
{</span><span class="identifier">
export_point</span><span class="special">();</span><span class="identifier">
export_triangle</span><span class="special">();</span><span class="special">
}</span></tt></pre>
<p>
Compiling and linking together all this files produces the same result as
the usual approach:
</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="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">triangle</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>
Compiling and linking together all this files produces the same result as the
usual approach:</p>
<pre class="programlisting"><tt class="literal"><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="preprocessor">
#include</span><span class="special"> &lt;</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span><span class="preprocessor">
#include</span><span class="special"> &lt;</span><span class="identifier">triangle</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span><span class="identifier">
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">&gt;(</span><span class="string">"point"</span><span class="special">)...;</span>
<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">triangle</span><span class="special">&gt;(</span><span class="string">"triangle"</span><span class="special">)...;</span>
<span class="special">}</span>
</pre>
BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span><span class="special">
{</span><span class="identifier">
class_</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">&gt;(</span><span class="string">"point"</span><span class="special">)...;</span><span class="identifier">
class_</span><span class="special">&lt;</span><span class="identifier">triangle</span><span class="special">&gt;(</span><span class="string">"triangle"</span><span class="special">)...;</span><span class="special">
}</span></tt></pre>
<p>
but the memory is kept under control.
</p>
but the memory is kept under control.</p>
<p>
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.
</p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> If you're exporting your classes with <a href="../../../../../pyste/index.html" target="_top">Pyste</a>,
take a look at the <tt class="literal">--multiple</tt> option, that generates the
wrappers in various files as demonstrated here.
</p>
<p class="blurb">
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> This method is useful too if you are getting the error
message <span class="emphasis"><em>"fatal error C1204:Compiler limit:internal structure
overflow"</em></span> when compiling a large source file, as explained
in the <a href="../../../../v2/faq.html#c1204" target="_top">FAQ</a>.
</p>
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.</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/note.png"></span> If you're exporting your classes with <a href="../../../../../pyste/index.html" target="_top">Pyste</a>,
take a look at the <tt class="literal">--multiple</tt> option, that generates the wrappers in
various files as demonstrated here.</td></tr></tbody>
</table></div>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<span class="inlinemediaobject"><img src="../images/note.png"></span> This method is useful too if you are getting the error message
<span class="emphasis"><em>"fatal error C1204:Compiler limit:internal structure overflow"</em></span> when compiling
a large source file, as explained in the <a href="../../../../v2/faq.html#c1204" target="_top">FAQ</a>.</td></tr></tbody>
</table></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright © 2002-2005 Joel
de Guzman, David Abrahams</small></td>
<td align="right"><small>Copyright © 2002-2004 Joel de Guzman, David Abrahams</small></td>
</tr></table>
<hr>
<div class="spirit-nav">

View File

@@ -1,7 +1,7 @@
[library python
[version 1.0]
[authors [de Guzman, Joel], [Abrahams, David]]
[copyright 2002 2003 2004 2005 Joel de Guzman, David Abrahams]
[copyright 2002 2003 2004 Joel de Guzman, David Abrahams]
[category inter-language support]
[purpose
Reflects C++ classes and functions into Python
@@ -21,7 +21,6 @@
[def __alert__ [$images/alert.png]]
[def __tip__ [$images/tip.png]]
[def :-) [$images/smiley.png]]
[def __jam__ [$images/jam.png]]
[section QuickStart]
@@ -59,14 +58,10 @@ can be exposed to Python by writing a Boost.Python wrapper:
That's it. We're done. We can now build this as a shared library. The
resulting DLL is now visible to Python. Here's a sample Python session:
[python]
>>> import hello
>>> print hello.greet()
hello, world
[c++]
[:['[*Next stop... Building your Hello World module from start to finish...]]]
[endsect]
@@ -120,54 +115,46 @@ platforms. The complete list of Bjam executables can be found
[@http://sourceforge.net/project/showfiles.php?group_id=7586 here].
[h2 Let's Jam!]
__jam__
[$../images/jam.png]
Here is our minimalist Jamfile:
[pre
# This is the top of our own project tree
project-root ;
subproject libs/python/example/tutorial ;
import python ;
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
extension hello # Declare a Python extension called hello
: hello.cpp # source
# requirements and dependencies for Boost.Python extensions
<template>@boost/libs/python/build/extension
;
extension hello # Declare a Python extension called hello
: hello.cpp # source
<dll>../../build/boost_python # dependencies
;
]
First, we need to specify our location. You may place your project anywhere.
[^project-root] allows you to do that.
First, we need to specify our location in the boost project hierarchy.
It so happens that the tutorial example is located in [^/libs/python/example/tutorial].
Thus:
[pre
project-root ;
subproject libs/python/example/tutorial ;
]
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:
Then we will include the definitions needed by Python modules:
[pre
import python ;
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
]
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
;
extension hello # Declare a Python extension called hello
: hello.cpp # source
<dll>../../build/boost_python # dependencies
;
]
The last part tells BJam that we are depending on the Boost Python Library.
[h2 Running bjam]
['bjam] is run using your operating system's command line interpreter.
@@ -178,38 +165,29 @@ 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:
[pre
C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat
]
C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
Some environment variables will have to be setup for proper building of our
Python modules. Example:
[pre
set PYTHON_ROOT=c:/dev/tools/python
set PYTHON_VERSION=2.2
]
set PYTHON_ROOT=c:/dev/tools/python
set PYTHON_VERSION=2.2
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
and that we are using Python version 2.2. You'll have to tweak this path
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.
Now we are ready... Be sure to [^cd] to [^libs/python/example/tutorial]
where the tutorial [^"hello.cpp"] and the [^"Jamfile"] is situated.
Finally:
bjam -sTOOLS=vc-7_1
bjam -sTOOLS=msvc
We are again assuming that we are using Microsoft Visual C++ version 7.1. If
We are again assuming that we are using Microsoft Visual C++ version 6. If
not, then you will have to specify the appropriate tool. See
[@../../../../../../tools/build/index.html Building Boost Libraries] for
further details.
@@ -217,26 +195,26 @@ further details.
It should be building now:
[pre
cd C:\dev\boost\libs\python\example\tutorial
bjam -sTOOLS=msvc
...patience...
...found 1703 targets...
...updating 40 targets...
cd C:\dev\boost\libs\python\example\tutorial
bjam -sTOOLS=msvc
...patience...
...found 1703 targets...
...updating 40 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...
vc-C++ ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
runtime-link-dynamic\hello.obj
hello.cpp
vc-Link ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
runtime-link-dynamic\hello.pyd ..\..\..\..\libs\python\example\tutorial\bin\
hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib
Creating library ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\
msvc\debug\runtime-link-dynamic\hello.lib and object ..\..\..\..\libs\python\
example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp
...updated 40 targets...
]
If all is well, you should now have:
@@ -251,22 +229,19 @@ if you are on Windows, and
if you are on Unix.
[^boost_python.dll] and [^hello.pyd] can be found somewhere in your project's
[^bin] directory. After a successful build, you 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.)
[^boost_python.dll] can be found somewhere in [^libs\python\build\bin]
while [^hello.pyd] can be found somewhere in
[^libs\python\example\tutorial\bin]. After a successful build, you can just
link in these DLLs with the Python interpreter. In Windows for example, you
can simply put these libraries inside the directory where the Python
executable is.
You may now fire up Python and run our hello module:
[python]
>>> import hello
>>> print hello.greet()
hello, world
[c++]
[:[*There you go... Have fun!]]
[endsect]
@@ -301,8 +276,6 @@ Here, we wrote a C++ class wrapper that exposes the member functions
[^greet] and [^set]. Now, after building our module as a shared library, we
may use our class [^World] in Python. Here's a sample Python session:
[python]
>>> import hello
>>> planet = hello.World()
>>> planet.set('howdy')
@@ -321,8 +294,6 @@ which is why we were able to write
We may wish to wrap a class with a non-default constructor. Let us
build on our previous example:
[c++]
struct World
{
World(std::string msg): msg(msg) {} // added constructor
@@ -393,8 +364,6 @@ Our C++ [^Var] class and its data members can be exposed to Python:
Then, in Python, assuming we have placed our Var class inside the namespace
hello as we did before:
[python]
>>> x = hello.Var('pi')
>>> x.value = 3.14
>>> print x.name, 'is around', x.value
@@ -403,10 +372,12 @@ hello as we did before:
Note that [^name] is exposed as [*read-only] while [^value] is exposed
as [*read-write].
[pre
>>> x.name = 'e' # can't change name
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: can't set attribute
]
[endsect]
[section Class Properties]
@@ -417,8 +388,6 @@ the class' data members. The only way to access the class' data is
through access (getter/setter) functions. Access functions expose class
properties. Here's an example:
[c++]
struct Num
{
Num();
@@ -438,8 +407,6 @@ attributes can just be a different syntax for a method call. Wrapping our
And at last, in Python:
[python]
>>> x = Num()
>>> x.value = 3.14
>>> x.value, x.rovalue
@@ -449,8 +416,6 @@ And at last, in Python:
Take note that the class property [^rovalue] is exposed as [*read-only]
since the [^rovalue] setter member function is not passed in:
[c++]
.add_property("rovalue", &Num::get)
[endsect]
@@ -548,7 +513,7 @@ 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
[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
`return call<int>(this->get_override("f").ptr());`.]
@@ -573,7 +538,7 @@ correspond roughly to C++'s [*member functions]]
[section Virtual Functions with Default Implementations]
We've seen in the previous section how classes with pure virtual functions are
wrapped using Boost.Python's [@../../../v2/wrapper.html class wrapper]
wrapped using Boost.Python's [@../../../v2//wrapper.html class wrapper]
facilities. If we wish to wrap [*non]-pure-virtual functions instead, the
mechanism is a bit different.
@@ -612,7 +577,7 @@ We wrap it this way:
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\n\n
If you are using Microsoft Visual C++ 6 or 7, you have to rewrite the line
with the `*note*` as:\n\n
`return call<char const*>(f.ptr());`.]
@@ -630,8 +595,6 @@ special [^def] function for this purpose.
In Python, the results would be as expected:
[python]
>>> base = Base()
>>> class Derived(Base):
... def f(self):
@@ -661,8 +624,6 @@ this and makes it easy to wrap C++ operator-powered classes.
Consider a file position class [^FilePos] and a set of operators that take
on FilePos instances:
[c++]
class FilePos { /*...*/ };
FilePos operator+(FilePos, int);
@@ -700,13 +661,13 @@ similar set of intuitive interfaces can also be used to wrap C++ functions
that correspond to these Python ['special functions]. Example:
class Rational
{ public: operator double() const; };
{ operator double() const; };
Rational pow(Rational, Rational);
Rational abs(Rational);
ostream& operator<<(ostream&,Rational);
class_<Rational>("Rational")
class_<Rational>()
.def(float_(self)) // __float__
.def(pow(self, other<Rational>)) // __pow__
.def(abs(self)) // __abs__
@@ -715,9 +676,9 @@ that correspond to these Python ['special functions]. Example:
Need we say more?
[blurb __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))`.]
[blurb __note__ What is the business of [^operator<<] [^.def(str(self))]?
Well, the method [^str] requires the [^operator<<] to do its work (i.e.
[^operator<<] is used by the method defined by def(str(self)).]
[endsect]
[endsect] [/ Exposing Classes ]
@@ -737,27 +698,27 @@ But before you do, you might want to fire up Python 2.2 or later and type
[^>>> import this].
[pre
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
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 *right* 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!
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
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 *right* 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!
]
[section Call Policies]
@@ -810,8 +771,6 @@ Here's what's happening:
We could copy result into a new object:
[python]
>>> f(y, z).set(42) # Result disappears
>>> y.x.get() # No crash, but still bad
3.14
@@ -822,8 +781,6 @@ closely as possible.
Our problems do not end there. Suppose Y is implemented as follows:
[c++]
struct Y
{
X x; Z* z;
@@ -1100,7 +1057,7 @@ overloaded functions in one-shot:
Then...
.def("foo", (void(*)(bool, int, char))0, foo_overloads());
.def("foo", foo, foo_overloads());
Notice though that we have a situation now where we have a minimum of zero
(0) arguments and a maximum of 3 arguments.
@@ -1160,8 +1117,6 @@ Class [^object] wraps [^PyObject*]. All the intricacies of dealing with
To illustrate, this Python code snippet:
[python]
def f(x, y):
if (y == 'foo'):
x[3:7] = 'bar'
@@ -1174,8 +1129,6 @@ To illustrate, this Python code snippet:
Can be rewritten in C++ using Boost.Python facilities this way:
[c++]
object f(object x, object y) {
if (y == "foo")
x.slice(3,7) = "bar";
@@ -1241,22 +1194,18 @@ member functions.
Demonstrates that you can write the C++ equivalent of [^"format" % x,y,z]
in Python, which is useful since there's no easy way to do that in std C++.
[blurb
__alert__ [*Beware] the common pitfall of forgetting that the constructors
of most of Python's mutable types make copies, just as in Python.
]
__alert__ [*Beware] the common pitfall of forgetting that the constructors
of most of Python's mutable types make copies, just as in Python.
Python:
[python]
>>> d = dict(x.__dict__) # copies x.__dict__
>>> d['whatever'] = 3 # modifies the copy
>>> d['whatever'] # modifies the copy
C++:
[c++]
dict d(x.attr("__dict__")); // copies x.__dict__
d['whatever'] = 3; // modifies the copy
dict d(x.attr("__dict__")); # copies x.__dict__
d['whatever'] = 3; # modifies the copy
[h2 class_<T> as objects]
@@ -1290,15 +1239,16 @@ 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
by the Boost.Python [^object].
The first line attempts to extract the "length" attribute of the
Boost.Python [^object] [^o]. The second line attempts to ['extract] the
[^Vec2] object from held by the Boost.Python [^object] [^o].
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:
Take note that we said "attempt to" above. What if the Boost.Python
[^object] [^o] 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);
if (x.check()) {
@@ -1308,7 +1258,7 @@ __tip__ The astute reader might have noticed that the [^extract<T>]
facility in fact solves the mutable copying problem:
dict d = extract<dict>(x.attr("__dict__"));
d["whatever"] = 3; // modifies x.__dict__ !
d['whatever'] = 3; # modifies x.__dict__ !
[endsect]
@@ -1342,16 +1292,12 @@ attributes. Details can be found [@../../../v2/scope.html here].]
You can access those values in Python as
[python]
>>> my_module.choice.red
my_module.choice.red
where my_module is the module where the enum is declared. You can also
create a new scope around a class:
[c++]
scope in_X = class_<X>("X")
.def( ... )
.def( ... )
@@ -1416,20 +1362,20 @@ include path.
In a Jamfile, all the above boils down to:
[pre
projectroot c:\projects\embedded_program ; # location of the program
projectroot c:\projects\embedded_program ; # location of the program
# bring in the rules for python
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
# bring in the rules for python
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
exe embedded_program # name of the executable
: #sources
embedded_program.cpp
: # requirements
<find-library>boost_python <library-path>c:\boost\libs\python
$(PYTHON_PROPERTIES)
<library-path>$(PYTHON_LIB_PATH)
<find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
exe embedded_program # name of the executable
: #sources
embedded_program.cpp
: # requirements
<find-library>boost_python <library-path>c:\boost\libs\python
$(PYTHON_PROPERTIES)
<library-path>$(PYTHON_LIB_PATH)
<find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
]
[h2 Getting started]
@@ -1551,19 +1497,17 @@ the object's [^ptr] member function to retrieve the [^PyObject*].
This should create a file called 'hello.txt' in the current directory
containing a phrase that is well-known in programming circles.
[blurb
__note__ [*Note] that we wrap the return value of PyRun_String in a
(nameless) [^handle] even though we are not interested in it. If we didn't
do this, the the returned object would be kept alive unnecessarily. Unless
you want to be a Dr. Frankenstein, always wrap [^PyObject*]s in [^handle]s.
]
__note__ [*Note] that we wrap the return value of PyRun_String in a
(nameless) [^handle] even though we are not interested in it. If we didn't
do this, the the returned object would be kept alive unnecessarily. Unless
you want to be a Dr. Frankenstein, always wrap [^PyObject*]s in [^handle]s.
[h2 Beyond handles]
It's nice that [^handle] manages the reference counting details for us, but
other than that it doesn't do much. Often we'd like to have a more useful
class to manipulate Python objects. But we have already seen such a class
above, and in the [@python/object.html previous section]: the aptly
above, and in the [@object.html previous section]: the aptly
named [^object] class and it's derivatives. We've already seen that they
can be constructed from a [^handle]. The following examples should further
illustrate this fact:
@@ -1598,12 +1542,10 @@ PyRun_String return the result directly with Py_eval_input:
int five_squared = extract<int>(result);
[blurb
__note__ [*Note] that [^object]'s member function to return the wrapped
[^PyObject*] is called [^ptr] instead of [^get]. This makes sense if you
take into account the different functions that [^object] and [^handle]
perform.
]
__note__ [*Note] that [^object]'s member function to return the wrapped
[^PyObject*] is called [^ptr] instead of [^get]. This makes sense if you
take into account the different functions that [^object] and [^handle]
perform.
[h2 Exception handling]
@@ -1692,8 +1634,6 @@ iterators, but these are two very different beasts.
The typical Python iteration protocol: [^[*for y in x...]] is as follows:
[python]
iter = x.__iter__() # get iterator
try:
while 1:
@@ -1703,11 +1643,9 @@ The typical Python iteration protocol: [^[*for y in x...]] is as follows:
Boost.Python provides some mechanisms to make C++ iterators play along
nicely as Python iterators. What we need to do is to produce
appropriate `__iter__` function from C++ iterators that is compatible
appropriate __iter__ function from C++ iterators that is compatible
with the Python iteration protocol. For example:
[c++]
object get_iterator = iterator<vector<int> >();
object iter = get_iterator(v);
object first = iter.next();
@@ -1739,8 +1677,6 @@ with &T::begin, &T::end.
Let's put this into action... Here's an example from some hypothetical
bogon Particle accelerator code:
[python]
f = Field()
for x in f.pions:
smash(x)
@@ -1749,44 +1685,10 @@ bogon Particle accelerator code:
Now, our C++ Wrapper:
[c++]
class_<F>("Field")
.property("pions", range(&F::p_begin, &F::p_end))
.property("bogons", range(&F::b_begin, &F::b_end));
[*stl_input_iterator]
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
implement a function that exposes `std::list<int>::assign()` to
Python:
[c++]
template<typename T>
void list_assign(std::list<T>& l, object o) {
// Turn a Python sequence into an STL input range
stl_input_iterator<T> begin(o), end;
l.assign(begin, end);
}
// Part of the wrapper for list<int>
class_<std::list<int> >("list_int")
.def("assign", &list_assign<int>)
// ...
;
Now in Python, we can assign any integer sequence to `list_int` objects:
[python]
x = list_int();
x.assign([1,2,3,4,5])
[endsect]
[section:exception Exception Translation]
@@ -1872,14 +1774,14 @@ Unix and [^.dll] for Windows, works just as well.]
Now, we create this directory structure for our Python package:
[pre
sounds/
\_\_init\_\_.py
core.pyd
filters.pyd
io.pyd
sounds/
__init__.py
core.pyd
filters.pyd
io.pyd
]
The file [^\_\_init\_\_.py] is what tells Python that the directory [^sounds/] is
The file [^__init__.py] is what tells Python that the directory [^sounds/] is
actually a Python package. It can be a empty file, but can also perform some
magic, that will be shown later.
@@ -1887,8 +1789,6 @@ Now our package is ready. All the user has to do is put [^sounds] into his
[@http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000 PYTHONPATH]
and fire up the interpreter:
[python]
>>> import sounds.io
>>> import sounds.filters
>>> sound = sounds.io.open('file.mp3')
@@ -1906,8 +1806,6 @@ it.
If we want this flexibility, we will have to complicate our package hierarchy a
little. First, we will have to change the name of the extension modules:
[c++]
/* file core.cpp */
BOOST_PYTHON_MODULE(_core)
{
@@ -1920,32 +1818,30 @@ be changed to [^_core.pyd] as well, and we do the same to the other extension mo
Now, we change our package hierarchy like so:
[pre
sounds/
\_\_init\_\_.py
core/
\_\_init\_\_.py
_core.pyd
filters/
\_\_init\_\_.py
_filters.pyd
io/
\_\_init\_\_.py
_io.pyd
sounds/
__init__.py
core/
__init__.py
_core.pyd
filters/
__init__.py
_filters.pyd
io/
__init__.py
_io.pyd
]
Note that we created a directory for each extension module, and added a
\_\_init\_\_.py to each one. But if we leave it that way, the user will have to
__init__.py to each one. But if we leave it that way, the user will have to
access the functions in the core module with this syntax:
[python]
>>> import sounds.core._core
>>> sounds.core._core.foo(...)
which is not what we want. But here enters the [^\_\_init\_\_.py] magic: everything
that is brought to the [^\_\_init\_\_.py] namespace can be accessed directly by the
which is not what we want. But here enters the [^__init__.py] magic: everything
that is brought to the [^__init__.py] namespace can be accessed directly by the
user. So, all we have to do is bring the entire namespace from [^_core.pyd]
to [^core/\_\_init\_\_.py]. So add this line of code to [^sounds/core/\_\_init\_\_.py]:
to [^core/__init__.py]. So add this line of code to [^sounds/core/__init__.py]:
from _core import *
@@ -1968,7 +1864,7 @@ create a file named [^sounds/filters/echo_noise.py] and code our function:
s = _filters.noise(sound)
return s
Next, we add this line to [^sounds/filters/\_\_init\_\_.py]:
Next, we add this line to [^sounds/filters/__init__.py]:
from echo_noise import echo_noise
@@ -2003,8 +1899,6 @@ Yes, Python rox. :-)
We can do the same with classes that were wrapped with Boost.Python. Suppose
we have a class [^point] in C++:
[c++]
class point {...};
BOOST_PYTHON_MODULE(_geom)
@@ -2014,9 +1908,7 @@ we have a class [^point] in C++:
If we are using the technique from the previous session,
[link python.creating_packages Creating Packages], we can code directly
into [^geom/\_\_init\_\_.py]:
[python]
into [^geom/__init__.py]:
from _geom import *
@@ -2085,8 +1977,6 @@ time to compile the Boost.Python wrappers. Plus the memory consumption can
easily become too high. If this is causing you problems, you can split the
class_ definitions in multiple files:
[c++]
/* file point.cpp */
#include <point.h>
#include <boost/python.hpp>

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,10 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatic redirection failed, click this
<a href="doc/html/index.html">link</a> &nbsp;<hr>
<p>© Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
<a href="doc/html/index.html">link</a>
</body>
</html>
</html>

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

32
doc/v2/bibliography.html Normal file
View File

@@ -0,0 +1,32 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Bibliography</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Bibliography</h2>
</td>
</tr>
</table>
<hr>
{{bibliographical information}}
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. </i></p>
</body>
</html>

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -82,7 +79,7 @@ call_method&lt;ResultType&gt;(self_object, "<i>method-name</i>", a1, a2... a<i>N
the arguments <code>a1</code>...<code>a<i>N</i></code> are copied into
new Python objects, but this behavior can be overridden by the use of
<code><a href="ptr.html#ptr-spec">ptr()</a></code> and <a href=
"../../../bind/ref.html">ref()</a>:</p>
"../../../bind/ref.html#reference_wrapper">ref()</a>:</p>
<pre>
class X : boost::noncopyable
{
@@ -131,7 +128,7 @@ void apply(PyObject* callable, X&amp; x)
<tr>
<td><code><a href=
"../../../bind/ref.html">boost::reference_wrapper</a>&lt;T&gt;</code></td>
"../../../bind/ref.html#reference_wrapper">boost::reference_wrapper</a>&lt;T&gt;</code></td>
<td>The Python argument contains a pointer to, rather than a copy of,
<code>x.get()</code>. Note: failure to ensure that no Python code

View File

@@ -1,7 +1,3 @@
.. Copyright David Abrahams 2006. 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)
Here's the plan:
I aim to provide an interface similar to that of Boost.Python v1's

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -132,6 +132,4 @@ BOOST_PYTHON_MODULE(my_ext)
</p>
<p><i>&copy; Copyright Joel de Guzman 2003. </i> 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)
<p><i>&copy; Copyright Joel de Guzman 2003. </i>

View File

@@ -165,8 +165,6 @@ struct return_value_policy : Base
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002.</i> 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)</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. </i>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,339 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 1st September 2004), see www.w3.org">
<meta http-equiv="Content-Type" content=
"text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python -
&lt;boost/python/docstring_options.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%"
summary="header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width=
"277" alt="C++ Boost" src="../../../../boost.png" border=
"0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href=
"../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/docstring_options.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#docstring_options-spec">Class
<code>docstring_options</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#docstring_options-spec-synopsis">Class
<code>docstring_options</code> synopsis</a></dt>
<dt><a href="#docstring_options-spec-ctors">Class
<code>docstring_options</code> constructors</a></dt>
<dt><a href="#docstring_options-spec-dtors">Class
<code>docstring_options</code> destructors</a></dt>
<dt><a href="#docstring_options-spec-modifiers">Class
<code>docstring_options</code> modifiers</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Examples</a></dt>
</dl>
<hr>
<h2><a name="introduction" id=
"introduction"></a>Introduction</h2>
<p>Boost.Python supports user-defined docstrings with automatic
appending of C++ signatures. These features are enabled by
default. The <code>class docstring_options</code> is available to
selectively suppress the user-defined docstrings, signatures, or
both.</p>
<h2><a name="classes" id="classes"></a>Classes</h2>
<h3><a name="docstring_options-spec" id=
"docstring_options-spec"></a>Class
<code>docstring_options</code></h3>
<p>Controls the appearance of docstrings of wrapped functions and
member functions for the life-time of the instance. The instances
are noncopyable to eliminate the possibility of surprising side
effects.</p>
<h4><a name="docstring_options-spec-synopsis" id=
"docstring_options-spec-synopsis"></a>Class
<code>docstring_options</code> synopsis</h4>
<pre>
namespace boost { namespace python {
class docstring_options : boost::noncopyable
{
public:
docstring_options(bool show_all=true);
docstring_options(bool show_user_defined, bool show_signatures);
~docstring_options();
void
disable_user_defined();
void
enable_user_defined();
void
disable_signatures();
void
enable_signatures();
void
disable_all();
void
enable_all();
};
}}
</pre>
<h4><a name="docstring_options-spec-ctors" id=
"docstring_options-spec-ctors"></a>Class
<code>docstring_options</code> constructors</h4>
<pre>
docstring_options(bool show_all=true);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Constructs a <code>docstring_options</code>
object which controls the appearance of function and
member-function docstrings defined in the code that follows. If
<code>show_all</code> is <code>true</code>, both the
user-defined docstrings and the automatically generated C++
signatures are shown. If <code>show_all</code> is
<code>false</code> the <code>__doc__</code> attributes are
<code>None</code>.</dt>
</dl>
<pre>
docstring_options(bool show_user_defined, bool show_signatures);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Constructs a <code>docstring_options</code>
object which controls the appearance of function and
member-function docstrings defined in the code that follows.
Iff <code>show_user_defined</code> is <code>true</code>, the
user-defined docstrings are shown. Iff
<code>show_signatures</code> is <code>true</code>, C++
signatures are automatically added. If both
<code>show_user_defined</code> and <code>show_signatures</code>
are <code>false</code>, the <code>__doc__</code> attributes are
<code>None</code>.</dt>
</dl>
<h4><a name="docstring_options-spec-dtors" id=
"docstring_options-spec-dtors"></a>Class
<code>docstring_options</code> destructors</h4>
<pre>
~docstring_options();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Restores the previous state of the
docstring options. In particular, if
<code>docstring_options</code> instances are in nested C++
scopes the settings effective in the enclosing scope are
restored. If the last <code>docstring_options</code> instance
goes out of scope the default "all on" settings are
restored.</dt>
</dl>
<h4><a name="docstring_options-spec-modifiers" id=
"docstring_options-spec-modifiers"></a>Class
<code>docstring_options</code> modifier functions</h4>
<pre>
void disable_user_defined();
void enable_user_defined();
void disable_signatures();
void enable_signatures();
void disable_all();
void enable_all();
</pre>
<dl class="function-semantics">
<dt>These member functions dynamically change the appearance of
docstrings in the code that follows. The
<code>*_user_defined()</code> and <code>*_signatures()</code>
member functions are provided for fine-grained control. The
<code>*_all()</code> member functions are convenient shortcuts
to manipulate both settings simultaneously.</dt>
</dl>
<h2><a name="examples" id="examples"></a>Examples</h2>
<h4>Docstring options defined at compile time</h4>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/docstring_options.hpp&gt;
void foo() {}
BOOST_PYTHON_MODULE(demo)
{
using namespace boost::python;
docstring_options doc_options(DEMO_DOCSTRING_SHOW_ALL);
def("foo", foo, "foo doc");
}
</pre>If compiled with <code>-DDEMO_DOCSTRING_SHOW_ALL=true</code>:
<pre>
&gt;&gt;&gt; import demo
&gt;&gt;&gt; print demo.foo.__doc__
foo doc
C++ signature:
foo(void) -&gt; void
</pre>If compiled with
<code>-DDEMO_DOCSTRING_SHOW_ALL=false</code>:
<pre>
&gt;&gt;&gt; import demo
&gt;&gt;&gt; print demo.foo.__doc__
None
</pre>
<h4>Selective suppressions</h4>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/args.hpp&gt;
#include &lt;boost/python/docstring_options.hpp&gt;
int foo1(int i) { return i; }
int foo2(long l) { return static_cast&lt;int&gt;(l); }
int foo3(float f) { return static_cast&lt;int&gt;(f); }
int foo4(double d) { return static_cast&lt;int&gt;(d); }
BOOST_PYTHON_MODULE(demo)
{
using namespace boost::python;
docstring_options doc_options;
def("foo1", foo1, arg("i"), "foo1 doc");
doc_options.disable_user_defined();
def("foo2", foo2, arg("l"), "foo2 doc");
doc_options.disable_signatures();
def("foo3", foo3, arg("f"), "foo3 doc");
doc_options.enable_user_defined();
def("foo4", foo4, arg("d"), "foo4 doc");
}
</pre>Python code:
<pre>
&gt;&gt;&gt; import demo
&gt;&gt;&gt; print demo.foo1.__doc__
foo1 doc
C++ signature:
foo1(int i) -&gt; int
&gt;&gt;&gt; print demo.foo2.__doc__
C++ signature:
foo2(long l) -&gt; int
&gt;&gt;&gt; print demo.foo3.__doc__
None
&gt;&gt;&gt; print demo.foo4.__doc__
foo4 doc
</pre>
<h4>Wrapping from multiple C++ scopes</h4>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/args.hpp&gt;
#include &lt;boost/python/docstring_options.hpp&gt;
int foo1(int i) { return i; }
int foo2(long l) { return static_cast&lt;int&gt;(l); }
int bar1(int i) { return i; }
int bar2(long l) { return static_cast&lt;int&gt;(l); }
namespace {
void wrap_foos()
{
using namespace boost::python;
// no docstring_options here
// -&gt; settings from outer C++ scope are in effect
def("foo1", foo1, arg("i"), "foo1 doc");
def("foo2", foo2, arg("l"), "foo2 doc");
}
void wrap_bars()
{
using namespace boost::python;
bool show_user_defined = true;
bool show_signatures = false;
docstring_options doc_options(show_user_defined, show_signatures);
def("bar1", bar1, arg("i"), "bar1 doc");
def("bar2", bar2, arg("l"), "bar2 doc");
}
}
BOOST_PYTHON_MODULE(demo)
{
boost::python::docstring_options doc_options(false);
wrap_foos();
wrap_bars();
}
</pre>Python code:
<pre>
&gt;&gt;&gt; import demo
&gt;&gt;&gt; print demo.foo1.__doc__
None
&gt;&gt;&gt; print demo.foo2.__doc__
None
&gt;&gt;&gt; print demo.bar1.__doc__
bar1 doc
&gt;&gt;&gt; print demo.bar2.__doc__
bar2 doc
</pre>
<h4>See also: <code>boost/libs/python/test/docstring.cpp</code>
and <code>docstring.py</code></h4>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
16 January, 2006
<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
<p><i>&copy; Copyright <a href=
"../../../../people/ralf_w_grosse_kunstleve.htm">Ralf W.
Grosse-Kunstleve</a> 2006.</i></p>
</body>
</html>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -129,7 +126,7 @@ void handle_exception() throw();
<dt><b>Rationale:</b> At inter-language boundaries it is important to
ensure that no C++ exceptions escape, since the calling language
usually doesn't have the equipment necessary to properly unwind the
usually doesn't have the equipment neccessary to properly unwind the
stack. Use <code>handle_exception</code> to manage exception
translation whenever your C++ code is called directly from the Python
API. This is done for you automatically by the usual function wrapping
@@ -137,7 +134,7 @@ void handle_exception() throw();
"make_function.html#make_function-spec">make_function</a>()</code>,
<code><a href=
"make_function.html#make_constructor-spec">make_constructor</a>()</code>,
<code><a href="def.html#class_-spec-modifiers">def</a>()</code> and <code><a href=
<code><a href="def.html#def-spec">def</a>()</code> and <code><a href=
"class.html#def-spec">class_::def</a>()</code>. The second form can be
more convenient to use (see the <a href="#examples">example</a> below),
but various compilers have problems when exceptions are rethrown from

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,145 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/exec.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/exec.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#exec-spec"><code>exec</code></a></dt>
<dt><a href="#exec_file-spec"><code>exec_file</code></a></dt>
</dl>
</dd>
<dt><a href="#examples">Examples</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>Exposes a mechanism for embedding the python interpreter into C++ code.</p>
<h2><a name="functions"></a>Functions</h2>
<h3><a name="exec-spec"></a><code>exec</code></h3>
<pre>
object exec(str code,
object globals = object(),
object locals = object());
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
Execute Python source code from <code>code</code> in the context
specified by the dictionaries <code>globals</code> and <code>locals</code>.
</dt>
<dt><b>Returns:</b>
An instance of <a href="object.html#object-spec">object</a>
which holds the result of executing the code.
</dt>
</dl>
<h3><a name="exec_file-spec"></a><code>exec_file</code></h3>
<pre>
object exec_file(str filename,
object globals = object(),
object locals = object());
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
Execute Python source code from the file named by <code>filename</code>
in the context specified by the dictionaries <code>globals</code> and
<code>locals</code>.
</dt>
<dt><b>Returns:</b>
An instance of <a href="object.html#object-spec">object</a>
which holds the result of executing the code.
</dt>
</dl>
<h2><a name="examples"></a>Examples</h2>
<para>The following example demonstrates the use of <function>import</function>
and <function>exec</function> to define a function in python, and later call
it from within C++.</para>
<pre>
#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace boost::python;
void greet()
{
// Retrieve the main module.
object main = import("__main__");
// Retrieve the main module's namespace
object global(main.attr("__dict__"));
// Define greet function in Python.
object result = exec(
"def greet(self): \n"
" return 'Hello from Python!' \n",
global, global);
// Create a reference to it.
object greet = global["greet"];
// Call it.
std::string message = extract&lt;std::string&gt;(greet());
std::cout &lt;&lt; message &lt;&lt; std::endl;
}
</pre>
<para>Instead of embedding the python script into a string,
we could also store it in an a file...</para>
<pre>
def greet(self):
return 'Hello from Python!'
</pre>
<para>... and execute that instead.</para>
<pre>
// ...
// Load the greet function from a file.
object result = exec_file(script, global, global);
// ...
}
</pre>
<p>Revised 01 November, 2005</p>
<p><i>&copy; Copyright Stefan Seefeld 2005.</i></p>
</body>
</html>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -70,6 +67,8 @@
>error C2064: term does not evaluate to a function taking 2 arguments</a>
</dt>
<dt><a href="#voidptr">How do I handle <tt>void *</tt> conversion?</a></dt>
<dt><a href="#custom_string"
>How can I automatically convert my custom string type to
and from a Python string?</a></dt>
@@ -569,7 +568,7 @@ handle&lt;&gt; f_wrap()
...
def("f", f_wrap());
class_&lt;X,X_wrap,boost::noncopyable&gt;("X", init&lt;int&gt;())
class_&lt;X,X_wrap&gt;("X", init&lt;int&gt;())
...
;
</pre>
@@ -694,6 +693,29 @@ void Export_FXThread()
.def("setAutoDelete", (bool (FXThread::*)(bool)) &amp;FXThread::setAutoDelete)</pre>
<p>(The bug has been reported to Microsoft.)</p>
<hr>
<h2><a name="voidptr"></a>How do I handle <tt>void *</tt> conversion?</h2>
<font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
For several reasons Boost.Python does not support <tt>void *</tt> as
an argument or as a return value. However, it is possible to wrap
functions with <tt>void *</tt> arguments or return values using
thin wrappers and the <i>opaque pointer</i> facility. E.g.:
<pre>// Declare the following in each translation unit
struct void_ {};
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(void_);
void *foo(int par1, void *par2);
void_ *foo_wrapper(int par1, void_ *par2)
{
return (void_ *) foo(par1, par2);
}
...
BOOST_PYTHON_MODULE(bar)
{
def("foo", &amp;foo_wrapper);
}</pre>
<hr>
<h2><a name="custom_string"></a>How can I automatically
convert my custom string type to and from a Python string?</h2>
@@ -851,11 +873,11 @@ BOOST_PYTHON_MODULE(custom_string)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
12 March, 2006
28 January, 2004
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002-2006.</i></p>
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002-2003.</i></p>
</body>
</html>

View File

@@ -360,8 +360,7 @@
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p class="c3">&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. 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)</p>
<p class="c3">&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002.

165
doc/v2/from_python.html Normal file
View File

@@ -0,0 +1,165 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/from_python.hpp&gt;</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/from_python.hpp&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#from_python-spec">Class
Template<code>from_python</code></a>
<dd>
<dl class="page-index">
<dt><a href="#from_python-spec-synopsis">Class Template
<code>from_python</code> synopsis</a>
<dt><a href="#from_python-spec-ctors">Class Template
<code>from_python</code> constructor</a>
<dt><a href="#from_python-spec-observers">Class Template
<code>from_python</code> observer functions</a>
</dl>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/from_python.hpp&gt;</code> introduces a class
template <code>from_python&lt;T&gt;</code> for extracting a C++ object of
type <code>T</code> from a Python object.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="from_python-spec"></a>Class Template
<code>from_python&lt;class T&gt;</code></h3>
<p><code>from_python&lt;T&gt;</code> is the type used internally by
Boost.Python to extract C++ function arguments from a Python argument tuple
when calling a wrapped function. It can also be used directly to make
similar conversions in other contexts.
<h4><a name="from_python-spec-synopsis"></a>Class Template
<code>from_python</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T&gt;
struct from_python : private <a href=
"../../../utility/utility.htm#Class_noncopyable">boost::noncopyable</a> // Exposition only.
// from_python&lt;T&gt; meets the NonCopyable requirements
{
from_python(PyObject*);
bool convertible() const;
<i>convertible-to-T</i> operator()(PyObject*) const;
};
}
</pre>
<h4><a name="from_python-spec-ctors"></a>Class Template
<code>from_python</code> constructor</h4>
<pre>
from_python(PyObject* p);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>p != 0</code>
<dt><b>Effects:</b> Constructs a <code>from_python</code> object suitable
for extracting a C++ object of type <code>T</code> from <code>p</code>.
</dl>
<h4><a name="from_python-spec-observers"></a>Class Template
<code>from_python</code> observer functions</h4>
<pre>
bool convertible() const;
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> <code>false</code> if the conversion cannot succeed.
This indicates that either:
<dd>
<ol>
<li>No <code>from_python_converter</code> was registered for
<code>T</code>, or
<li>any such converter rejected the constructor argument
<code>p</code> by returning <code>0</code> from its
<code>convertible()</code> function
</ol>
Note that conversion may still fail in <code>operator()</code> due to
an exception.
<dt><b>Throws:</b> nothing
<dt><b>Rationale:</b> Because <code>from_python&lt;&gt;</code> is used in
overload resolution, and throwing an exception can be slow, it is useful
to be able to rule out a broad class of unsuccessful conversions without
throwing an exception.
</dl>
<pre>
<i>convertible-to-T</i> operator()(PyObject* p) const;
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>*p</code> refers to the same object which was
passed to the constructor, and <code>convertible()</code> returns
<code>true</code>.
<dt><b>Effects:</b> performs the conversion
<dt><b>Returns:</b> an object convertible to <code>T</code>.
</dl>
<h2><a name="examples"></a>Example</h2>
<pre>
#include &lt;string&gt;
#include &lt;boost/python/from_python.hpp&gt;
// If a std::string can be extracted from p, return its
// length. Otherwise, return 0.
std::size_t length_if_string(PyObject* p)
{
from_python&lt;std::string&gt; converter(p);
if (!converter.convertible())
return 0;
else
return converter(p).size();
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. </i>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

288
doc/v2/header.html Normal file
View File

@@ -0,0 +1,288 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;{{header}}&gt;</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;{{header}}&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#macros">Macros</a>
<dd>
<dl class="page-index">
<dt><a href="#macro-spec">{{macro name}}</a>
</dl>
<dt><a href="#values">Values</a>
<dd>
<dl class="page-index">
<dt><a href="#value-spec">{{value name}}</a>
</dl>
<dt><a href="#types">Types</a>
<dd>
<dl class="page-index">
<dt><a href="#type-spec">{{type name}}</a>
</dl>
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#class-spec">Class <code>{{name}}</code></a>
<dd>
<dl class="page-index">
<dt><a href="#class-spec-synopsis">Class <code>{{name}}</code> synopsis</a>
<dt><a href="#class-spec-ctors">Class <code>{{name}}</code>
constructors and destructor</a>
<dt><a href="#class-spec-comparisons">Class <code>{{name}}</code> comparison functions</a>
<dt><a href="#class-spec-modifiers">Class <code>{{name}}</code> modifier functions</a>
<dt><a href="#class-spec-observers">Class <code>{{name}}</code> observer functions</a>
<dt><a href="#class-spec-statics">Class <code>{{name}}</code> static functions</a>
</dl>
</dl>
<dt><a href="#functions">Functions</a>
<dd>
<dl class="page-index">
<dt><a href="#function-spec">{{function name}}</a>
</dl>
<dt><a href="#objects">Objects</a>
<dd>
<dl class="page-index">
<dt><a href="#object-spec">{{object name}}</a>
</dl>
<dt><a href="#examples">Example(s)</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>{{Introductory text}}
<h2><a name="macros"></a>Macros</h2>
<p><a name="macro-spec"></a>{{Macro specifications}}
<h2><a name="values"></a>Values</h2>
<p><a name="value-spec"></a>{{Value specifications}}
<h2><a name="types"></a>Types</h2>
<p><a name="type-spec"></a>{{Type specifications}}
<h2><a name="classes"></a>Classes</h2>
<h3><a name="class-spec"></a>Class <code>{{name}}</code></h3>
<p>{{class overview text}}
<h4><a name="class-spec-synopsis"></a>Class <code>{{name}}</code> synopsis</h4>
<pre>
namespace boost
{
class {{name}}
{
};
};
</pre>
<h4><a name="class-spec-ctors"></a>Class <code>{{name}}</code> constructors and
destructor</h4>
<pre>
{{constructor}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<pre>
{{destructor}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h4><a name="class-spec-comparisons"></a>Class <code>{{name}}</code> comparison
functions</h4>
<pre>
{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h4><a name="class-spec-modifiers"></a>Class <code>{{name}}</code> modifier
functions</h4>
<pre>
{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h4><a name="class-spec-observers"></a>Class <code>{{name}}</code> observer
functions</h4>
<pre>
{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h4><a name="class-spec-statics"></a>Class <code>{{name}}</code> static functions</h4>
<pre>
{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name="function-spec"></a>{{function}}
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> {{text}}
<dt><b>Effects:</b> {{text}}
<dt><b>Postconditions:</b> {{text}}
<dt><b>Returns:</b> {{text}}
<dt><b>Throws:</b> {{text}}
<dt><b>Complexity:</b> {{text}}
<dt><b>Rationale:</b> {{text}}
</dl>
<h2><a name="objects"></a>Objects</h2>
<p><a name="object-spec"></a>{{Object specifications}}
<h2><a name="examples"></a>Example(s)</h2>
<p>{{Example(s)}}
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. </i>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -113,7 +110,7 @@ using namespace boost::python;
struct X
{
X(int x) : v(x) {}
operator int() const { return v; }
operator int() { return v; }
int v;
};

View File

@@ -1,90 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/import.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/import.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#import-spec"><code>import</code></a></dt>
</dl>
</dd>
<dt><a href="#examples">Examples</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>Exposes a mechanism for importing python modules.</p>
<h2><a name="functions"></a>Functions</h2>
<h3><a name="import-spec"></a><code>import</code></h3>
<pre>
object import(str name);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Imports the module named by <code>name</code>.</dt>
<dt><b>Returns:</b> An instance of <a href="object.html#object-spec">object</a>
which holds a reference to the imported module.</dt>
</dl>
<h2><a name="examples"></a>Examples</h2>
<para>The following example demonstrates the use of <function>import</function>
to access a function in python, and later call it from within C++.</para>
<pre>
#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace boost::python;
void print_python_version()
{
// Load the sys module.
object sys = import("sys");
// Extract the python version.
std::string version = extract&lt;std::string&gt;(sys.attr("version"));
std::cout &lt;&lt; version &lt;&lt; std::endl;
}
</pre>
<p>Revised 01 November, 2005</p>
<p><i>&copy; Copyright Stefan Seefeld 2005.</i></p>
</body>
</html>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,7 +1,4 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -69,8 +66,8 @@
</dt>
<dt>
<a href="#vector_indexing_suite_class">vector_indexing_suite
class<br>
</a><a href="#map_indexing_suite_class">map_indexing_suite class</a> </dt>
class</a>
</dt>
</dl>
<hr>
<h2>
@@ -144,7 +141,7 @@
<h3> <a name="indexing_suite"></a>indexing_suite [ Header &lt;boost/python/indexing/indexing_suite.hpp&gt;
]</h3>
<p>
The <tt>indexing_suite</tt> class is the base class for the
The <tt>indexing_suite</tt> class is the base protocol class for the
management of C++ containers intended to be integrated to Python. The
objective is make a C++ container look and feel and behave exactly as
we'd expect a Python container. The class automatically wraps these
@@ -278,7 +275,8 @@
The <tt>vector_indexing_suite</tt> class is a predefined
<tt>indexing_suite</tt> derived class designed to wrap
<tt>std::vector</tt> (and <tt>std::vector</tt> like [i.e. a class with
std::vector interface]) classes. It provides all the policies required by the
std::vector interface]) classes (currently, this is the only predefined
suite available). It provides all the policies required by the
<tt>indexing_suite</tt>.
</p>
<p>
@@ -297,32 +295,22 @@
<a href="../../test/vector_indexing_suite.cpp">example in full</a>,
along with its <a href="../../test/vector_indexing_suite.py">python
test</a>).
</p>
<h3><a name="map_indexing_suite" id="map_indexing_suite"></a>map_indexing_suite [ Header &lt;boost/python/indexing/map_indexing_suite.hpp&gt; ] </h3>
<p> The <tt>map_indexing_suite</tt> class is a predefined <tt>indexing_suite</tt> derived class designed to wrap <tt>std::map</tt> (and <tt>std::map</tt> like [i.e. a class with std::map interface]) classes. It provides all the policies required by the <tt>indexing_suite</tt>. </p>
<p> Example usage: </p>
<pre>
class X {...};
...
class_&lt;std::map&lt;X&gt; &gt;("XMap")
.def(map_indexing_suite&lt;std::map&lt;X&gt; &gt;())
;
</pre>
<p> By default indexed elements are returned by proxy. This can be disabled by supplying <tt>true</tt> in the NoProxy template parameter. <tt>XMap</tt> is now a full-fledged Python container (see the <a href="../../test/map_indexing_suite.cpp">example in full</a>, along with its <a href="../../test/map_indexing_suite.py">python test</a>).</p>
</p>
<hr>
<h2>
<a name="indexing_suite_class"></a>indexing_suite class </h2>
<h2> <tt>indexing_suite&lt;<br>
</tt><tt>class Container<br>
<a name="indexing_suite_class"></a>indexing_suite class
</h2>
<h3>
<br>
<tt>indexing_suite&lt;<br>
class Container<br>
, class DerivedPolicies<font color="#007F00"><br>
</font></tt> <tt>,
bool NoProxy<br>
,
bool NoSlice<br>
</tt><tt>, class Data<br>
, class Index<br>
</tt><tt>, class Key</tt></h2>
bool NoProxy<br>
, class Element<br>
, class Key<br>
, class Index</tt>
</h3>
<table width="100%" border="1">
<tr>
<td>
@@ -367,45 +355,36 @@
</td>
</tr>
<tr>
<td> <font color="#007F00"><tt>NoProxy</tt></font> </td>
<td> A boolean </td>
<td> By default indexed elements have Python reference semantics and are returned by proxy. This can be disabled by supplying <strong>true</strong> in the <tt>NoProxy</tt> template parameter. </td>
<td> false </td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>NoSlice</tt></font>
<font color="#007F00"><tt>NoProxy</tt></font>
</td>
<td>
A boolean
</td>
<td>
Do not allow slicing. </td>
By default indexed elements have Python reference semantics and are
returned by proxy. This can be disabled by supplying
<strong>true</strong> in the <tt>NoProxy</tt> template parameter.
</td>
<td>
false
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Data</tt></font>
<font color="#007F00"><tt>Element</tt></font>
</td>
<td>&nbsp;
</td>
<td>
The container's data type.
The container's element type.
</td>
<td>
<tt>Container::value_type</tt>
</td>
</tr>
<tr>
<td> <font color="#007F00"><tt>Index</tt></font> </td>
<td>&nbsp; </td>
<td> The container's index type. </td>
<td> <tt>Container::size_type</tt> </td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Key</tt></font>
@@ -420,14 +399,28 @@
<tt>Container::value_type</tt>
</td>
</tr>
</table>
<tr>
<td>
<font color="#007F00"><tt>Index</tt></font>
</td>
<td>&nbsp;
</td>
<td>
The container's index type.
</td>
<td>
<tt>Container::size_type</tt>
</td>
</tr>
</table>
<pre>
template &lt;<br> class Container
, class DerivedPolicies
, bool NoProxy = false<br> , bool NoSlice = false
, class Data = typename Container::value_type
, class Index = typename Container::size_type
, bool NoProxy = false
, class Element = typename Container::value_type
, class Key = typename Container::value_type
, class Index = typename Container::size_type
&gt;<br> class indexing_suite
: unspecified
{
@@ -442,22 +435,23 @@
<dl>
<dd>
Derived classes provide the hooks needed by
the <tt>indexing_suite:</tt>
the<tt>indexing_suite:</tt>
</dd>
</dl>
<pre> data_type&amp;
<pre>
static element_type&amp;
get_item(Container&amp; container, index_type i);
static object
get_slice(Container&amp; container, index_type from, index_type to);
static void
set_item(Container&amp; container, index_type i, data_type const&amp; v);
set_item(Container&amp; container, index_type i, element_type const&amp; v);
static void
set_slice(
Container&amp; container, index_type from,
index_type to, data_type const&amp; v
index_type to, element_type const&amp; v
);
template &lt;class Iter&gt;
@@ -599,16 +593,16 @@
</tr>
</table>
<pre>
template &lt;<br> class Container,<br> bool NoProxy = false,<br> class DerivedPolicies = unspecified_default<br> class vector_indexing_suite : unspecified_base<br> {<br> public:<br><br> typedef typename Container::value_type data_type;<br> typedef typename Container::value_type key_type;<br> typedef typename Container::size_type index_type;<br> typedef typename Container::size_type size_type;<br> typedef typename Container::difference_type difference_type;<br> <br> data_type&amp;<br> get_item(Container&amp; container, index_type i);
template &lt;<br> class Container,<br> bool NoProxy = false,<br> class DerivedPolicies = unspecified_default<br> class vector_indexing_suite<br> : public indexing_suite&lt;Container, DerivedPolicies, NoProxy&gt;<br> {<br> public:<br><br> typedef typename Container::value_type element_type;<br> typedef typename Container::value_type key_type;<br> typedef typename Container::size_type index_type;<br> typedef typename Container::size_type size_type;<br> typedef typename Container::difference_type difference_type;<br> <br> static element_type&amp;<br> get_item(Container&amp; container, index_type i);
static object
get_slice(Container&amp; container, index_type from, index_type to);
static void<br> set_item(Container&amp; container, index_type i, data_type const&amp; v);
static void<br> set_item(Container&amp; container, index_type i, element_type const&amp; v);
static void
set_slice(Container&amp; container, index_type from,
index_type to, data_type const&amp; v);
index_type to, element_type const&amp; v);
template &lt;class Iter&gt;<br> static void<br> set_slice(Container&amp; container, index_type from,<br> index_type to, Iter first, Iter last);
@@ -630,60 +624,7 @@
adjust_index(index_type current, index_type from,
index_type to, size_type len);
};
</pre>
<h2><a name="vector_indexing_suite_class"></a>map_indexing_suite class </h2>
<h3> Class template <tt><br>
map_indexing_suite&lt;<br>
class <font color="#007F00">Container</font><br>
, bool <font color="#007F00">NoProxy</font><br>
, class <font color="#007F00">DerivedPolicies</font>&gt;</tt> </h3>
<table width="100%" border="1">
<tr>
<td> <strong>Template Parameter</strong><br>
</td>
<td> <strong>Requirements</strong> </td>
<td> <strong>Semantics</strong> </td>
<td> <strong>Default</strong> </td>
</tr>
<tr>
<td> <font color="#007F00"><tt>Container</tt></font> </td>
<td> A class type </td>
<td> The container type to be wrapped to Python. </td>
<td>&nbsp; </td>
</tr>
<tr>
<td> <font color="#007F00"><tt>NoProxy</tt></font> </td>
<td> A boolean </td>
<td> By default indexed elements have Python reference semantics and are returned by proxy. This can be disabled by supplying <strong>true</strong> in the <tt>NoProxy</tt> template parameter. </td>
<td> false </td>
</tr>
<tr>
<td> <font color="#007F00"><tt>DerivedPolicies</tt></font> </td>
<td> A subclass of indexing_suite </td>
<td> The <tt>vector_indexing_suite</tt> may still be derived to further tweak any of the predefined policies. Static polymorphism through CRTP (James Coplien. "Curiously Recurring Template Pattern". C++ Report, Feb. 1995) enables the base <tt>indexing_suite</tt> class to call policy function of the most derived class </td>
<td>&nbsp; </td>
</tr>
</table>
<pre>
template &lt;<br> class Container,<br> bool NoProxy = false,<br> class DerivedPolicies = unspecified_default<br> class map_indexing_suite : unspecified_base<br> {<br> public:<br><br> typedef typename Container::value_type value_type;<br> typedef typename Container::value_type::second_type data_type;<br> typedef typename Container::key_type key_type;<br> typedef typename Container::key_type index_type;<br> typedef typename Container::size_type size_type;<br> typedef typename Container::difference_type difference_type;<br><br> static data_type&amp;<br> get_item(Container&amp; container, index_type i);
static void<br> set_item(Container&amp; container, index_type i, data_type const&amp; v);
static void
delete_item(Container&amp; container, index_type i);<br>
static size_t
size(Container&amp; container);
static bool
contains(Container&amp; container, key_type const&amp; key);
static bool<br> compare_index(Container&amp; container, index_type a, index_type b);
<br> static index_type
convert_index(Container&amp; container, PyObject* i);
};
</pre>
</pre>
<hr>
&copy; Copyright Joel de Guzman 2003. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,9 +1,6 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content="HTML Tidy, see www.w3.org">

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -48,7 +45,7 @@
<dt><a href="#iterator-spec-synopsis">Class
<code>iterator</code> synopsis</a></dt>
<dt><a href="#iterator-spec-constructors">Class template
<dt><a href="#iterator-spec-ctors">Class template
<code>iterator</code> constructor</a></dt>
</dl>
</dd>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -71,7 +71,7 @@ This macro generates two functions in the scope where it is used:
and <code>void&nbsp;init_module_<i>name</i>()</code>, whose body must
follow the macro invocation. <code>init_<i>name</i></code> passes
<code>init_module_<i>name</i></code> to <code><a
href="errors.html#handle_exception-spec">handle_exception</a>()</code> so
href="errors.html#handle_exception">handle_exception</a>()</code> so
that any C++ exceptions generated are safely processeed. During the
body of <code>init_<i>name</i></code>, the current <code><a
href="scope.html#scope-spec">scope</a></code> refers to the module
@@ -104,7 +104,5 @@ RuntimeError: Unidentifiable C++ Exception
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. </i> 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)</p>
Abrahams</a> 2002. </i>

View File

@@ -1,105 +1,102 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="../boost.css">
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/numeric.hpp&gt;</title>
</head>
<title>Boost.Python - &lt;boost/python/numeric.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
</td>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/numeric.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2 align="center">Header &lt;boost/python/numeric.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#array-spec">Class <code>array</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#array-spec">Class <code>array</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#array-spec-synopsis">Class <code>array</code>
synopsis</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#array-spec-synopsis">Class <code>array</code>
synopsis</a></dt>
<dt><a href="#array-spec-observers">Class <code>array</code>
observer functions</a></dt>
<dt><a href="#array-spec-observers">Class <code>array</code>
observer functions</a></dt>
<dt><a href="#array-spec-statics">Class <code>array</code> static
functions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#array-spec-statics">Class <code>array</code>
static functions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction" id="introduction"></a>Introduction</h2>
<h2><a name="introduction"></a>Introduction</h2>
<p>Exposes a <a href=
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
<a href=
"http://www.python.org/dev/doc/devel/lib/typesmapping.html">array</a>
type.</p>
<p>Exposes a <a href=
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
<a href=
"http://www.python.org/dev/doc/devel/lib/typesmapping.html">array</a>
type.</p>
<h2><a name="classes" id="classes"></a>Classes</h2>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="array-spec" id="array-spec"></a>Class <code>array</code></h3>
<h3><a name="array-spec"></a>Class <code>array</code></h3>
<p>Provides access to the array types of <a href=
"http://www.pfdubois.com/numpy/">Numerical Python</a>'s <a href=
"http://www.pfdubois.com/numpy/#Numeric">Numeric</a> and <a href=
"http://stsdas.stsci.edu/numarray/index.html">NumArray</a> modules. With
the exception of the functions documented <a href=
"#array-spec-observers">below</a>, the semantics of the constructors and
member functions defined below can be fully understood by reading the
<a href="ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
definition. Since <code>array</code> is publicly derived from
<code><a href="object.html#object-spec">object</a></code>, the public
object interface applies to <code>array</code> instances as well.</p>
<p>Provides access to the array types of <a href=
"http://www.pfdubois.com/numpy/">Numerical Python</a>'s <a href=
"http://www.pfdubois.com/numpy/#Numeric">Numeric</a> and <a href=
"http://stsdas.stsci.edu/numarray/index.html">NumArray</a> modules. With
the exception of the functions documented <a href=
"#array-spec-observers">below</a>, the semantics of the constructors and
member functions defined below can be fully understood by reading the <a
href="ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
definition. Since <code>array</code> is publicly derived from <code><a
href="object.html#object-spec">object</a></code>, the public object
interface applies to <code>array</code> instances as well.</p>
<p><a name="default_search" id="default_search"></a>The default behavior is
to use <code>numarray.NDArray</code> as the associated Python type if the
<code>numarray</code> module is installed in the default location.
Otherwise it falls back to use <code>Numeric.ArrayType</code>. If neither
extension module is installed, overloads of wrapped C++ functions with
<code>numeric::array</code> parameters will never be matched, and other
attempted uses of <code>numeric::array</code> will <a href=
"definitions.html#raise">raise</a> an appropriate Python exception. The
associated Python type can be set manually using the <code><a href=
"#array-spec-statics">set_module_and_type</a>(...)</code> static
function.</p>
<p><a name="default_search"></a>The default behavior is to use
<code>numarray.NDArray</code> as the associated Python type if the
<code>numarray</code> module is installed in the default location.
Otherwise it falls back to use <code>Numeric.ArrayType</code>. If neither
extension module is installed, conversions to arguments of type
<code>numeric::array</code> will cause overload resolution to reject the
overload, and other attempted uses of <code>numeric::array</code> will <a
href="definitions.html#raise">raise</a> an appropriate Python exception.
The associated Python type can be set manually using the <code><a href=
"#array-spec-statics">set_module_and_type</a>(...)</code> static
function.</p>
<h4><a name="array-spec-synopsis" id="array-spec-synopsis"></a>Class
<code>array</code> synopsis</h4>
<pre>
<h4><a name="array-spec-synopsis"></a>Class <code>array</code>
synopsis</h4>
<pre>
namespace boost { namespace python { namespace numeric
{
class array : public object
@@ -110,7 +107,7 @@ namespace boost { namespace python { namespace numeric
object astype(Type const&amp; type_);
template &lt;class Type&gt;
array new_(Type const&amp; type_) const;
object new_(Type const&amp; type_) const;
template &lt;class Sequence&gt;
void resize(Sequence const&amp; x);
@@ -136,14 +133,14 @@ namespace boost { namespace python { namespace numeric
void tofile(File const&amp; f) const;
object factory();
template &lt;class Sequence&gt;
object factory(Sequence const&amp;);
template &lt;class Sequence, class Typecode&gt;
object factory(Sequence const&amp;, Typecode const&amp;, bool copy = true, bool savespace = false);
template &lt;class Sequence, class Typecode, class Type&gt;
object factory(Sequence const&amp;, Typecode const&amp;, bool copy, bool savespace, Type const&amp;);
template &lt;class Sequence, class Typecode, class Type, class Shape&gt;
object factory(Sequence const&amp;, Typecode const&amp;, bool copy, bool savespace, Type const&amp;, Shape const&amp;);
template &lt;class Buffer&gt;
object factory(Buffer const&amp;);
template &lt;class Buffer, class Type&gt;
object factory(Buffer const&amp;, Type const&amp;);
template &lt;class Buffer, class Type, class Shape&gt;
object factory(Buffer const&amp;, Type const&amp;, Shape const&amp;, bool copy = true, bool savespace = false);
template &lt;class Buffer, class Type, class Shape&gt;
object factory(Buffer const&amp;, Type const&amp;, Shape const&amp;, bool copy, bool savespace, char typecode);
template &lt;class T1&gt;
explicit array(T1 const&amp; x1);
@@ -155,7 +152,6 @@ namespace boost { namespace python { namespace numeric
static void set_module_and_type();
static void set_module_and_type(char const* package_path = 0, char const* type_name = 0);
static void get_module_name();
object argmax(long axis=-1);
@@ -204,60 +200,54 @@ namespace boost { namespace python { namespace numeric
}}}
</pre>
<h4><a name="array-spec-observers" id="array-spec-observers"></a>Class
<code>array</code> observer functions</h4>
<pre>
<h4><a name="array-spec-observers"></a>Class <code>array</code> observer
functions</h4>
<pre>
object factory();
template &lt;class Sequence&gt;
object factory(Sequence const&amp;);
template &lt;class Sequence, class Typecode&gt;
object factory(Sequence const&amp;, Typecode const&amp;, bool copy = true, bool savespace = false);
template &lt;class Sequence, class Typecode, class Type&gt;
object factory(Sequence const&amp;, Typecode const&amp;, bool copy, bool savespace, Type const&amp;);
template &lt;class Sequence, class Typecode, class Type, class Shape&gt;
object factory(Sequence const&amp;, Typecode const&amp;, bool copy, bool savespace, Type const&amp;, Shape const&amp;);
</pre>These functions map to the underlying array type's <code>array()</code>
function family. They are not called "<code>array</code>" because of the C++
limitation that you can't define a member function with the same name as its
enclosing class.
<pre>
template &lt;class Buffer&gt;
object factory(Buffer const&amp;);
template &lt;class Buffer, class Type&gt;
object factory(Buffer const&amp;, Type const&amp;);
template &lt;class Buffer, class Type, class Shape&gt;
object factory(Buffer const&amp;, Type const&amp;, Shape const&amp;, bool copy = true, bool savespace = false);
template &lt;class Buffer, class Type, class Shape&gt;
object factory(Buffer const&amp;, Type const&amp;, Shape const&amp;, bool copy, bool savespace, char typecode);
</pre>
These functions map to the underlying array type's <code>array()</code>
function family. They are not called "<code>array</code>" because of the
C++ limitation that you can't define a member function with the same name
as its enclosing class.
<pre>
template &lt;class Type&gt;
array new_(Type const&amp;) const;
</pre>This function maps to the underlying array type's <code>new()</code>
function. It is not called "<code>new</code>" because that is a keyword in
C++.
object new_(Type const&amp;) const;
</pre>
This function maps to the underlying array type's <code>new()</code>
function. It is not called "<code>new</code>" because that is a keyword
in C++.
<h4><a name="array-spec-statics" id="array-spec-statics"></a>Class
<code>array</code> static functions</h4>
<pre>
<h4><a name="array-spec-statics"></a>Class <code>array</code> static
functions</h4>
<pre>
static void set_module_and_type(char const* package_path, char const* type_name);
static void set_module_and_type();
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>package_path</code> and
<code>type_name</code>, if supplied, is an <a href=
"definitions.html#ntbs">ntbs</a>.</dt>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>package_path</code> and
<code>type_name</code>, if supplied, is an <a href=
"definitions.html#ntbs">ntbs</a>.</dt>
<dt><b>Effects:</b> The first form sets the package path of the module
that supplies the type named by <code>type_name</code> to
<code>package_path</code>. The second form restores the <a href=
"#default_search">default search behavior</a>. The associated Python type
will be searched for only the first time it is needed, and thereafter the
first time it is needed after an invocation of
<code>set_module_and_type</code>.</dt>
</dl>
<pre>
static std::string get_module_name()
</pre>
<dt><b>Effects:</b> The first form sets the package path of the module
which supplies the type named by <code>type_name</code> to
<code>package_path</code>. The second form restores the <a href=
"#default_search">default search behavior</a>. The associated Python
type will be searched for only the first time it is needed, and
thereafter the first time it is needed after an invocation of
<code>set_module_and_type</code>.</dt>
</dl>
<dl class="function-semantics">
<dt><b>Effects:</b> Returns the name of the module containing the class
that will be held by new <code>numeric::array</code> instances.</dt>
</dl>
<h2><a name="examples" id="examples"></a>Example</h2>
<pre>
<h2><a name="examples"></a>Example</h2>
<pre>
#include &lt;boost/python/numeric.hpp&gt;
#include &lt;boost/python/tuple.hpp&gt;
@@ -268,9 +258,10 @@ void set_first_element(numeric::array&amp; y, double value)
}
</pre>
<p>Revised 07 October, 2006</p>
<p>Revised 03 October, 2002</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2006.</i></p>
</body>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
</body>
</html>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -186,15 +183,10 @@
<dt><a href="#binary-spec">binary operations</a></dt>
<dt><a href="#assignment-spec">assignment operations</a></dt>
</dl>
<dl class="page-index">
<dt><a href="#object_operators-spec">operators</a></dt>
</dl>
<dl class="page-index">
<dt><a href="#len-spec">len()</a></dt>
<dt><a href="#operators-spec">operators</a></dt>
</dl>
</dd>
@@ -240,7 +232,7 @@ x[slice(_,_,-1)]
<p>The policies which are used for proxies representing an attribute
access to a <code>const&nbsp;object</code>.</p>
<h4><a name="const_attribute_policies-spec-synopsis"></a>Class
<h4><a name="class-spec-synopsis"></a>Class
<code>const_attribute_policies</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace api
@@ -854,12 +846,12 @@ void del(proxy&lt;T&gt; const&amp; x);
</dl>
<pre>
<a name="comparisons-spec"></a>
template&lt;class L,class R&gt; object operator&gt;(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; object operator&gt;=(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; object operator&lt;(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; object operator&lt;=(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; object operator==(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; object operator!=(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; bool operator&gt;(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; bool operator&gt;=(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; bool operator&lt;(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; bool operator&lt;=(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; bool operator==(L const&amp;l,R const&amp;r);
template&lt;class L,class R&gt; bool operator!=(L const&amp;l,R const&amp;r);
</pre>
<dl class="function-semantics">
@@ -908,16 +900,7 @@ template&lt;class R&gt; object&amp; operator|=(object&amp;l,R const&amp;r);
<dt><b>Returns:</b> <code>l</code>.</dt>
</dl>
<pre>
inline long len(object const&amp; obj);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> PyObject_Length(obj.ptr()) </dt>
<dt><b>Returns:</b> len() of object.</dt>
</dl>
<h2><a name="examples"></a>Example</h2>
<h2><a name="examples"></a>Example</h2>
Python code:
<pre>
def sum_items(seq):
@@ -931,18 +914,20 @@ def sum_items(seq):
object sum_items(object seq)
{
object result = object(0);
for (int i = 0; i &lt; len(seq); ++i)
for (int i = 0; i &lt; seq.attr("__len__")(); ++i)
result += seq[i];
return result;
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 January, 2006
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2006.</i></p>
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
</body>
</html>

View File

@@ -1,138 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright 2003..2006 Haufe Mediengruppe. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/opaque_pointer_converter.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/opaque_pointer_converter.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#opaque-spec">Class template
<code>opaque&lt;Pointee&gt;</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#opaque-spec-synopsis">Class template
<code>opaque</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#macros">Macros</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">Macro
<code>BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</code></a></dt>
</dl>
</dd>
<dt><a href="#see-also">See Also</a></dt>
</dl>
<hr>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="opaque-spec"></a>Class template
<code>opaque&lt;P&gt;</code></h3>
<p><code>opaque&lt;&gt;</code> registers itself as a converter from
Python objects to pointers to undefined types and vice versa.</p>
<h4><a name="opaque-spec-synopsis"></a>Class template
<code>opaque</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template&lt;class Pointee&gt;
struct opaque
{
opaque();
};
}}
</pre>
<h4><a name="opaque-spec-constructor"></a>Class template
<code>opaque</code> constructor</h4>
<pre>
opaque();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<ul>
<li>Registers the instance as a
<a href="lvalue_from_pytype.html#lvalue_from_pytype-spec"> <code>lvalue_from_pytype</code></a>
converter from Python objects into opaque pointers.</p>
<p>The Python Objects created are named after the type pointed to
by the opaque pointer being wrapped.</p></li>
<li>Registers the instance as a
<a href="to_python_converter.html#to_python_converter-spec"> <code>to_python_converter</code></a>
from opaque pointers to Python objects.</p></li>
</ul>
<p>If there is already an instance registered by another module, this
instance doesn't try to register again in order to avoid warnings
about multiple registrations.</p>
<h4>Note</h4>
<p>Normally only a single instance of this class is created for every
Pointee.</p>
</dt>
</dl>
<h2><a name="macros"></a>Macros</h2>
<h3><a name="BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec"></a>
Macro BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)</h3>
<p>This macro must be used to define specializations of the
<a href="type_id.html#type_id-spec">type_id</a> function
which can't be instantiated for incomplete types.</p>
<h4>Note</h4>
<p>The macro must be invoked in every translation unit which uses the
opaque converter.</p>
<h2><a name="see-also"></a>See Also</h2>
<p>
<a href="return_opaque_pointer.html">return_opaque_pointer</a>
</p>
<p>Revised
10 September, 2006
</p>
<p><i>&copy; Copyright 2003..2006 Haufe Mediengruppe. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -0,0 +1,142 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/opaque_pointer_converter.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/opaque_pointer_converter.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#opaque_pointer_converter-spec">Class template
<code>opaque_pointer_converter&lt;P&gt;</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#opaque_pointer_converter-spec-synopsis">Class template
<code>opaque_pointer_converter</code> synopsis</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#macros">Macros</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">Macro
<code>BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</code></a></dt>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
<dt><a href="#see-also">See Also</a></dt>
</dl>
<hr>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="opaque_pointer_converter-spec"></a>Class template
<code>opaque_pointer_converter&lt;P&gt;</code></h3>
<p><code>opaque_pointer_converter&lt;&gt;</code> is derived from
<a href="to_python_converter.html#to_python_converter-spec">
<code>to_python_converter</code></a>
and registers itself as an
<a href="lvalue_from_pytype.html#lvalue_from_pytype-spec">
<code>lvalue_from_pytype</code></a> converter from Python objects
into pointers to undefined types.
Thus it may be used as a converter from opaque pointers into
Python objects and vice versa.</p>
<h4><a name="opaque_pointer_converter-spec-synopsis"></a>Class template
<code>opaque_pointer_converter</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template&lt;class Pointer&gt;
struct opaque_pointer_converter
: to_python_converter&lt;
Pointer, opaque_pointer_converter&lt;Pointer&gt; &gt;
{
explicit opaque_pointer_converter(char const* name);
};
}}
</pre>
<h4><a name="opaque_pointer_converter-spec-constructor"></a>Class template
<code>opaque_pointer_converter</code> constructor</h4>
<pre>
explicit opaque_pointer_converter(char const* name);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<p>Registers the instance as a
<a href="lvalue_from_pytype.html#lvalue_from_pytype-spec">
<code>lvalue_from_pytype</code></a> converter from Python objects
into opaque pointers.</p>
<p>The name is used for the type of the Python Objects created;
it should be printable but needn't be an
<a href="definitions.html#ntbs">ntbs</a> because the object type is
not supposed to be user constructible within python scripts.</p>
</dt>
</dl>
<h2><a name="macros"></a>Macros</h2>
<h3><a name="BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec"></a>
Macro BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)</h3>
<p>This macro must be used to define specializations of the
<a href="type_id.html#type_id-spec">type_id</a> function
which can't be instantiated for incomplete types.</p>
<h4>Note</h4>
<p>In order for this to work in a cross-module environment the macro must
be invoked in every translation unit which uses the
opaque_pointer_converter.</p>
<h2><a name="examples"></a>Example</h2>
please see example for <a href="return_opaque_pointer.html#example">
return_opaque_pointer</a>.
<h2><a name="see-also"></a>See Also</h2>
<p>
<a href="return_opaque_pointer.html">return_opaque_pointer</a>
</p>
<p>Revised
10 March, 2003
</p>
<p><i>&copy; Copyright 2003 Haufe Mediengruppe. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -60,7 +57,7 @@
<dt><a href="#self_t-spec-value-unary-ops">Class
<code>self_t</code> unary operations</a></dt>
<dt><a href="#self_t-spec-value-ops">Class
<dt><a href="#self_t-spec-value-value-ops">Class
<code>self_t</code> value operations</a></dt>
</dl>
</dd>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

48
doc/v2/overview.html Normal file
View File

@@ -0,0 +1,48 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Overview</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Overview</h2>
</td>
</tr>
</table>
<hr>
<dl class="index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#topic1">First topic</a></dt>
<dt><a href="#topic2">Second topic</a></dt>
<dt><a href="#footnotes">Footnotes</a></dt>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>{{text}}</p>
<h2><a name="topic1"></a>First Topic</h2>
<p>{{text}}</p>
<h2><a name="topic2"></a>Second Topic</h2>
<p>{{text}}</p>
<h2><a name="footnotes"></a>Footnotes</h2>
<dl>
<dt><a name="footnote1" class="footnote">(1)</a> {{text}}</dt>
<dt><a name="footnote2" class="footnote">(2)</a> {{text}}</dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. </i></p>
</body>
</html>

View File

@@ -92,8 +92,8 @@ following examples.
<hr>
<h2>Examples</h2>
There are three files in
<tt>boost/libs/python/test</tt> that show how to
There are three files in <a href="../../test/"
><tt>boost/libs/python/test</tt></a> that show how to
provide pickle support.
<hr>
@@ -320,9 +320,11 @@ See also the
<hr>
&copy; Copyright Ralf W. Grosse-Kunstleve 2001-2004. 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)
&copy; Copyright Ralf W. Grosse-Kunstleve 2001-2004. Permission to copy,
use, modify, sell and distribute this document is granted provided this
copyright notice appears in all copies. This document is provided "as
is" without express or implied warranty, and with no claim as to its
suitability for any purpose.
<p>
Updated: Feb 2004.

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -54,11 +51,13 @@
3.1, and 3.2 on <a href="http://www.redhat.com">RedHat Linux 7.3</a>
for Intel x86</dt>
<dt>Tru64 CXX 6.5.1 on OSF v. 5.1 for Dec/Compaq
Alpha</dt>
<dt><a href=
"http://www.tru64unix.compaq.com/cplus/index.html">Tru64 CXX
6.5.1</a> on OSF v. 5.1 for Dec/Compaq Alpha</dt>
<dt>
MIPSPro 7.3.1.2m on <a href=
<dt><a href=
"http://www.sgi.com/developers/devtools/languages/mipspro.html">
MIPSPro 7.3.1.2m</a> on <a href=
"http://www.sgi.com/software/irix6.5/">IRIX 6.5</a> for SGI
mips</dt>
@@ -71,16 +70,21 @@
<dd>
<dl>
<dt>KCC 3.4d on OSF v. 5.1 for Dec/Compaq Alpha</dt>
<dt><a href=
"http://developer.intel.com/software/products/kcc/">KCC
3.4d</a> on OSF v. 5.1 for Dec/Compaq Alpha</dt>
<dt>KCC 3.4d</a> on AIX</dt>
<dt><a href=
"http://developer.intel.com/software/products/kcc/">KCC
3.4d</a> on AIX</dt>
</dl>
</dd>
</dl>
<br>
</dd>
<dt>Microsoft Windows XP Professional with Python <a href=
<dt><a href="http://www.microsoft.com/windowsxp/default.asp">Microsoft
Windows XP Professional</a> with Python <a href=
"http://www.python.org/2.2">2.2</a>, <a href=
"http://www.python.org/2.2.1">2.2.1</a>, and <a href=
"http://www.python.org/2.2.2">2.2.2b1</a>:</dt>

View File

@@ -45,8 +45,8 @@
<p><code>&lt;boost/python/pointee.hpp&gt;</code> introduces a
traits <a
href="../../../mpl/doc/refmanual/metafunction.html">metafunction</a>
template <code>pointee&lt;T&gt;</code> that can be used to extract the &quot;pointed-to&quot; type from the type of a pointer or smart pointer.
href="../../../mpl/doc/index.html#metafunctions">metafunction</a>
template <code>pointee&lt;T&gt;</code> which can be used to extract the &quot;pointed-to&quot; type from the type of a pointer or smart pointer.
<h2><a name="classes"></a>Classes</h2>
@@ -112,8 +112,5 @@ BOOST_PYTHON_MODULE(pointee_demo)
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. </i> 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)</p>
Abrahams</a> 2002. </i>

View File

@@ -1,6 +1,3 @@
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

View File

@@ -259,7 +259,5 @@ void pass_as_arg(expensive_to_copy* x, PyObject* f)
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. </i> 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)</p>
Abrahams</a> 2002. </i>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

48
doc/v2/rationale.html Normal file
View File

@@ -0,0 +1,48 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - Rationale</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Rationale</h2>
</td>
</tr>
</table>
<hr>
<dl class="index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#topic1">First topic</a></dt>
<dt><a href="#topic2">Second topic</a></dt>
<dt><a href="#footnotes">Footnotes</a></dt>
</dl>
<h2><a name="introduction"></a>Introduction</h2>
<p>{{text}}</p>
<h2><a name="topic1"></a>First Topic</h2>
<p>{{text}}</p>
<h2><a name="topic2"></a>Second Topic</h2>
<p>{{text}}</p>
<h2><a name="footnotes"></a>Footnotes</h2>
<dl>
<dt><a name="footnote1" class="footnote">(1)</a> {{text}}</dt>
<dt><a name="footnote2" class="footnote">(2)</a> {{text}}</dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. </i></p>
</body>
</html>

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=

View File

@@ -1,8 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Copyright David Abrahams 2006. 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) -->
<html>
<head>
<meta name="generator" content=
@@ -63,8 +60,6 @@
<dt><a href="#type_conversion">To/From Python Type Conversion</a></dt>
<dt><a href="#embedding">Embedding</a></dt>
<dt><a href="#utility">Utility and Infrastructure</a></dt>
<dt><a href="#topics">Topics</a></dt>
@@ -81,7 +76,7 @@
<dt><a href=
"Dereferenceable.html#Dereferenceable-concept">Dereferenceable</a></dt>
<dt><a href="Extractor.html#Extractor-concept">Extractor</a></dt>
<dt><a href="Dereferenceable.html#Extractor-concept">Extractor</a></dt>
<dt><a href=
"HolderGenerator.html#HolderGenerator-concept">HolderGenerator</a></dt>
@@ -140,14 +135,6 @@
</dl>
</dd>
<dt><a href="docstring_options.html">docstring_options.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="docstring_options.html#classes">Classes</a></dt>
</dl>
</dd>
<dt><a href="enum.html">enum.hpp</a></dt>
<dd>
@@ -304,20 +291,6 @@
</dl>
</dd>
<dt><a href="stl_iterator.html">stl_iterator.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="stl_iterator.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="stl_iterator.html#stl_input_iterator-spec">stl_input_iterator</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="wrapper.html">wrapper.hpp</a></dt>
<dd>
@@ -907,26 +880,26 @@
</dd>
<dt><a href=
"opaque.html">opaque_pointer_converter.hpp</a></dt>
"opaque_pointer_converter.html">opaque_pointer_converter.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
"opaque.html#classes">Classes</a></dt>
"opaque_pointer_converter.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href=
"opaque.html#opaque-spec">opaque</a></dt>
"opaque_pointer_converter.html#opaque_pointer_converter-spec">opaque_pointer_converter</a></dt>
</dl>
</dd>
<dt><a href="opaque.html#macros">Macros</a></dt>
<dt><a href="opaque_pointer_converter.html#macros">Macros</a></dt>
<dd>
<dl class="index">
<dt><a href=
"opaque.html#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">
"opaque_pointer_converter.html#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</a></dt>
</dl>
</dd>
@@ -966,39 +939,6 @@
</dd>
</dl>
<h2><a name="embedding">Embedding</a></h2>
<dl class="index">
<dt><a href="exec.html">exec.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="exec.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href="exec.html#exec-spec">exec</a></dt>
<dt><a href="exec.html#exec_file-spec">exec_file</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="import.html">import.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="import.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href="import.html#import-spec">import</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
<h2><a name="utility">Utility and Infrastructure</a></h2>
<dl>
@@ -1041,7 +981,7 @@
<dd>
<dl class="index">
<dt>class template <a href=
"pointee.html#pointee-spec">pointee</a></dt>
"pointee.html#pointee">pointee</a></dt>
</dl>
</dd>
</dl>
@@ -1094,16 +1034,6 @@
</dd>
</dl>
</dd>
<dt><a href="ssize_t.html">ssize_t.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="ssize_t.html#typedefs">Typedefs</a></dt>
<dt><a href="ssize_t.html#constants">Constants</a></dt>
</dl>
</dd>
</dl>
<h2><a name="topics">Topics</a></h2>

Some files were not shown because too many files have changed in this diff Show More