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:
@@ -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>
|
||||
<find-library>$(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"><></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">
|
||||
|
||||
@@ -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<...></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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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_<T> as objects</h2>
|
||||
<a name="id459043"></a>class_<T> as objects</h2>
|
||||
<p>
|
||||
Due to the dynamic nature of Boost.Python objects, any <tt class="literal">class_<T></tt> may
|
||||
also be one of these types! The following code snippet wraps the class
|
||||
|
||||
@@ -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">>>></span><span class="identifier"> import</span><span class="identifier"> sounds</span><span class="special">.</span><span class="identifier">io</span><span class="special">
|
||||
>>></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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user