• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Embedding</title>
5<link rel="stylesheet" href="../../boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../index.html" title="Boost.Python Tutorial">
8<link rel="up" href="../index.html" title="Boost.Python Tutorial">
9<link rel="prev" href="object.html" title="Object Interface">
10<link rel="next" href="iterators.html" title="Iterators">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="" width="" height="" src="../../images/boost.png"></td></tr></table>
14<hr>
15<div class="spirit-nav">
16<a accesskey="p" href="object.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../images/next.png" alt="Next"></a>
17</div>
18<div class="section">
19<div class="titlepage"><div><div><h2 class="title" style="clear: both">
20<a name="tutorial.embedding"></a><a class="link" href="embedding.html" title="Embedding">Embedding</a>
21</h2></div></div></div>
22<div class="toc"><dl class="toc"><dt><span class="section"><a href="embedding.html#tutorial.embedding.using_the_interpreter">Using the interpreter</a></span></dt></dl></div>
23<p>
24      By now you should know how to use Boost.Python to call your C++ code from Python.
25      However, sometimes you may need to do the reverse: call Python code from the
26      C++-side. This requires you to <span class="emphasis"><em>embed</em></span> the Python interpreter
27      into your C++ program.
28    </p>
29<p>
30      Currently, Boost.Python does not directly support everything you'll need when
31      embedding. Therefore you'll need to use the <a href="http://www.python.org/doc/current/api/api.html" target="_top">Python/C
32      API</a> to fill in the gaps. However, Boost.Python already makes embedding
33      a lot easier and, in a future version, it may become unnecessary to touch the
34      Python/C API at all. So stay tuned... <span class="inlinemediaobject"><img src="../../images/smiley.png"></span>
35    </p>
36<h3>
37<a name="tutorial.embedding.h0"></a>
38      <span class="phrase"><a name="tutorial.embedding.building_embedded_programs"></a></span><a class="link" href="embedding.html#tutorial.embedding.building_embedded_programs">Building
39      embedded programs</a>
40    </h3>
41<p>
42      To be able to embed python into your programs, you have to link to both Boost.Python's
43      as well as Python's own runtime library.
44    </p>
45<p>
46      Boost.Python's library comes in two variants. Both are located in Boost's
47      <code class="literal">/libs/python/build/bin-stage</code> subdirectory. On Windows, the
48      variants are called <code class="literal">boost_python.lib</code> (for release builds)
49      and <code class="literal">boost_python_debug.lib</code> (for debugging). If you can't
50      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.
51    </p>
52<p>
53      Python's library can be found in the <code class="literal">/libs</code> subdirectory
54      of your Python directory. On Windows it is called pythonXY.lib where X.Y is
55      your major Python version number.
56    </p>
57<p>
58      Additionally, Python's <code class="literal">/include</code> subdirectory has to be added
59      to your include path.
60    </p>
61<p>
62      In a Jamfile, all the above boils down to:
63    </p>
64<pre class="programlisting">projectroot c:\projects\embedded_program ; # location of the program
65
66# bring in the rules for python
67SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
68include python.jam ;
69
70exe embedded_program # name of the executable
71  : #sources
72     embedded_program.cpp
73  : # requirements
74     &lt;find-library&gt;boost_python &lt;library-path&gt;c:\boost\libs\python
75  $(PYTHON_PROPERTIES)
76    &lt;library-path&gt;$(PYTHON_LIB_PATH)
77    &lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
78</pre>
79<h3>
80<a name="tutorial.embedding.h1"></a>
81      <span class="phrase"><a name="tutorial.embedding.getting_started"></a></span><a class="link" href="embedding.html#tutorial.embedding.getting_started">Getting
82      started</a>
83    </h3>
84<p>
85      Being able to build is nice, but there is nothing to build yet. Embedding the
86      Python interpreter into one of your C++ programs requires these 4 steps:
87    </p>
88<div class="orderedlist"><ol class="orderedlist" type="1">
89<li class="listitem">
90          #include <code class="literal">&lt;boost/python.hpp&gt;</code>
91        </li>
92<li class="listitem">
93          Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652" target="_top">Py_Initialize</a>()
94          to start the interpreter and create the <code class="literal">__main__</code> module.
95        </li>
96<li class="listitem">
97          Call other Python C API routines to use the interpreter.
98        </li>
99</ol></div>
100<div class="note"><table border="0" summary="Note">
101<tr>
102<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td>
103<th align="left">Note</th>
104</tr>
105<tr><td align="left" valign="top"><p>
106        <span class="bold"><strong>Note that at this time you must not call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
107        to stop the interpreter. This may be fixed in a future version of boost.python.</strong></span>
108      </p></td></tr>
109</table></div>
110<p>
111      (Of course, there can be other C++ code between all of these steps.)
112    </p>
113<div class="blockquote"><blockquote class="blockquote"><p>
114        <span class="emphasis"><em><span class="bold"><strong>Now that we can embed the interpreter in
115        our programs, lets see how to put it to use...</strong></span></em></span>
116      </p></blockquote></div>
117<div class="section">
118<div class="titlepage"><div><div><h3 class="title">
119<a name="tutorial.embedding.using_the_interpreter"></a><a class="link" href="embedding.html#tutorial.embedding.using_the_interpreter" title="Using the interpreter">Using the interpreter</a>
120</h3></div></div></div>
121<p>
122        As you probably already know, objects in Python are reference-counted. Naturally,
123        the <code class="literal">PyObject</code>s of the Python C API are also reference-counted.
124        There is a difference however. While the reference-counting is fully automatic
125        in Python, the Python C API requires you to do it <a href="http://www.python.org/doc/current/c-api/refcounting.html" target="_top">by
126        hand</a>. This is messy and especially hard to get right in the presence
127        of C++ exceptions. Fortunately Boost.Python provides the <a href="../../reference/utility_and_infrastructure/boost_python_handle_hpp.html#utility_and_infrastructure.boost_python_handle_hpp.class_template_handle" target="_top">handle</a>
128        and <a href="../../reference/object_wrappers/boost_python_object_hpp.html#object_wrappers.boost_python_object_hpp.class_object" target="_top">object</a>
129        class templates to automate the process.
130      </p>
131<h3>
132<a name="tutorial.embedding.using_the_interpreter.h0"></a>
133        <span class="phrase"><a name="tutorial.embedding.using_the_interpreter.running_python_code"></a></span><a class="link" href="embedding.html#tutorial.embedding.using_the_interpreter.running_python_code">Running
134        Python code</a>
135      </h3>
136<p>
137        Boost.python provides three related functions to run Python code from C++.
138      </p>
139<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">eval</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">expression</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
140<span class="identifier">object</span> <span class="identifier">exec</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">code</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
141<span class="identifier">object</span> <span class="identifier">exec_file</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">filename</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
142</pre>
143<p>
144        eval evaluates the given expression and returns the resulting value. exec
145        executes the given code (typically a set of statements) returning the result,
146        and exec_file executes the code contained in the given file.
147      </p>
148<p>
149        There are also overloads taking <code class="computeroutput"><span class="keyword">char</span>
150        <span class="keyword">const</span><span class="special">*</span></code>
151        instead of str as the first argument.
152      </p>
153<p>
154        The <code class="literal">globals</code> and <code class="literal">locals</code> parameters are
155        Python dictionaries containing the globals and locals of the context in which
156        to run the code. For most intents and purposes you can use the namespace
157        dictionary of the <code class="literal">__main__</code> module for both parameters.
158      </p>
159<p>
160        Boost.python provides a function to import a module:
161      </p>
162<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">import</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
163</pre>
164<p>
165        import imports a python module (potentially loading it into the running process
166        first), and returns it.
167      </p>
168<p>
169        Let's import the <code class="literal">__main__</code> module and run some Python code
170        in its namespace:
171      </p>
172<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
173<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>
174
175<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"hello = file('hello.txt', 'w')\n"</span>
176                      <span class="string">"hello.write('Hello world!')\n"</span>
177                      <span class="string">"hello.close()"</span><span class="special">,</span>
178                      <span class="identifier">main_namespace</span><span class="special">);</span>
179</pre>
180<p>
181        This should create a file called 'hello.txt' in the current directory containing
182        a phrase that is well-known in programming circles.
183      </p>
184<h3>
185<a name="tutorial.embedding.using_the_interpreter.h1"></a>
186        <span class="phrase"><a name="tutorial.embedding.using_the_interpreter.manipulating_python_objects"></a></span><a class="link" href="embedding.html#tutorial.embedding.using_the_interpreter.manipulating_python_objects">Manipulating
187        Python objects</a>
188      </h3>
189<p>
190        Often we'd like to have a class to manipulate Python objects. But we have
191        already seen such a class above, and in the <a class="link" href="object.html" title="Object Interface">previous
192        section</a>: the aptly named <code class="literal">object</code> class and its derivatives.
193        We've already seen that they can be constructed from a <code class="literal">handle</code>.
194        The following examples should further illustrate this fact:
195      </p>
196<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
197<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>
198<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"result = 5 ** 2"</span><span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">);</span>
199<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>
200</pre>
201<p>
202        Here we create a dictionary object for the <code class="literal">__main__</code> module's
203        namespace. Then we assign 5 squared to the result variable and read this
204        variable from the dictionary. Another way to achieve the same result is to
205        use eval instead, which returns the result directly:
206      </p>
207<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
208<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>
209</pre>
210<h3>
211<a name="tutorial.embedding.using_the_interpreter.h2"></a>
212        <span class="phrase"><a name="tutorial.embedding.using_the_interpreter.exception_handling"></a></span><a class="link" href="embedding.html#tutorial.embedding.using_the_interpreter.exception_handling">Exception
213        handling</a>
214      </h3>
215<p>
216        If an exception occurs in the evaluation of the python expression, <a href="../../reference/high_level_components/boost_python_errors_hpp.html#high_level_components.boost_python_errors_hpp.class_error_already_set" target="_top">error_already_set</a>
217        is thrown:
218      </p>
219<pre class="programlisting"><span class="keyword">try</span>
220<span class="special">{</span>
221    <span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5/0"</span><span class="special">);</span>
222    <span class="comment">// execution will never get here:</span>
223    <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>
224<span class="special">}</span>
225<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&amp;)</span>
226<span class="special">{</span>
227    <span class="comment">// handle the exception in some way</span>
228<span class="special">}</span>
229</pre>
230<p>
231        The <code class="literal">error_already_set</code> exception class doesn't carry any
232        information in itself. To find out more about the Python exception that occurred,
233        you need to use the <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">exception
234        handling functions</a> of the Python C API in your catch-statement. This
235        can be as simple as calling <a href="http://www.python.org/doc/api/exceptionHandling.html#l2h-70" target="_top">PyErr_Print()</a>
236        to print the exception's traceback to the console, or comparing the type
237        of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
238        exceptions</a>:
239      </p>
240<pre class="programlisting"><span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&amp;)</span>
241<span class="special">{</span>
242    <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>
243    <span class="special">{</span>
244        <span class="comment">// handle ZeroDivisionError specially</span>
245    <span class="special">}</span>
246    <span class="keyword">else</span>
247    <span class="special">{</span>
248        <span class="comment">// print all other errors to stderr</span>
249        <span class="identifier">PyErr_Print</span><span class="special">();</span>
250    <span class="special">}</span>
251<span class="special">}</span>
252</pre>
253<p>
254        (To retrieve even more information from the exception you can use some of
255        the other exception handling functions listed <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">here</a>.)
256      </p>
257</div>
258</div>
259<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
260<td align="left"></td>
261<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
262      de Guzman, David Abrahams<p>
263        Distributed under the Boost Software License, Version 1.0. (See accompanying
264        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>
265      </p>
266</div></td>
267</tr></table>
268<hr>
269<div class="spirit-nav">
270<a accesskey="p" href="object.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../images/next.png" alt="Next"></a>
271</div>
272</body>
273</html>
274