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

New Wrapper Facility

[SVN r26208]
This commit is contained in:
Joel de Guzman
2004-11-15 06:43:54 +00:00
parent 168c8c692a
commit 9ccde24cff
5 changed files with 37 additions and 38 deletions

View File

@@ -39,7 +39,7 @@ 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="id461362"></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>
@@ -48,7 +48,7 @@ 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
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
@@ -75,7 +75,7 @@ In a Jamfile, all the above boils down to:</p>
&lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
</tt></pre>
<a name="embedding.getting_started"></a><h2>
<a name="id461454"></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
@@ -113,7 +113,7 @@ 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="id461585"></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
@@ -146,7 +146,7 @@ discuss in the next section.</p>
</td></tr></tbody>
</table></div>
<a name="using_the_interpreter.running_python_code"></a><h2>
<a name="id461888"></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
@@ -161,7 +161,7 @@ The <tt class="literal">start</tt> parameter is the start symbol from the Python
for interpreting the code. The possible values are:</p>
<div class="informaltable">
<h4>
<a name="id462050"></a><span class="table-title">Start symbols</span>
<a name="id461201"></a><span class="table-title">Start symbols</span>
</h4>
<table class="table">
<colgroup>
@@ -224,12 +224,12 @@ containing a phrase that is well-known in programming circles.</p>
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="id462488"></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" title=" Object Interface">previous section</a>: the aptly
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>
@@ -266,12 +266,12 @@ int</span><span class="identifier"> five_squared</span><span class="special"> =<
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="id463061"></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
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">
@@ -290,14 +290,13 @@ catch</span><span class="special">(</span><span class="identifier">error_already
// 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>
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">
@@ -311,11 +310,11 @@ standard exceptions</a>:</p>
}</span><span class="special">
}</span></tt></pre>
<p>
(To retrieve even more information from the exception you can use some of the other
(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
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">

View File

@@ -172,7 +172,7 @@ A reference to <tt class="literal">y.x</tt> is returned
<li><span class="bold"><b>BOOM!</b></span></li>
</ol></div>
<a name="call_policies.call_policies"></a><h2>
<a name="id455009"></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>
@@ -335,7 +335,7 @@ are overloaded with a common sequence of initial arguments
</li>
</ul></div>
<a name="default_arguments.boost_python_function_overloads"></a><h2>
<a name="id456828"></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"><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">
@@ -354,7 +354,7 @@ and the maximum number of arguments is 4. The <tt class="literal">def(...)</tt>
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="id457107"></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
@@ -386,7 +386,7 @@ fourth macro argument). The thin wrappers are all enclosed in a class named
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="id457435"></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,
@@ -441,7 +441,7 @@ Then...</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="id458082"></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

View File

@@ -26,7 +26,7 @@
<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="id376618"></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
@@ -92,11 +92,11 @@ minimalist <span class="emphasis"><em>bjam</em></span> script that builds the DL
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
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="id378092"></a>Let's Jam!</h2>
<p><span class="inlinemediaobject"><img src="../images/jam.png"></span></p>
<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 ;
@@ -128,7 +128,7 @@ Finally we declare our <tt class="literal">hello</tt> extension:</p>
;
</tt></pre>
<a name="hello.running_bjam"></a><h2>
<a name="id378186"></a>Running bjam</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>

View File

@@ -42,7 +42,7 @@ 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>
<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>
@@ -146,7 +146,7 @@ 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="id459892"></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

View File

@@ -102,7 +102,7 @@ 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>
<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">
@@ -212,7 +212,7 @@ BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier"
}</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
<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>