mirror of
https://github.com/boostorg/python.git
synced 2026-01-24 06:02:14 +00:00
103 lines
7.9 KiB
HTML
103 lines
7.9 KiB
HTML
<html>
|
|
<head>
|
|
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
|
<title>Embedding with Boost.Python</title>
|
|
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
|
<link rel="prev" href="embedding_basics.html">
|
|
</head>
|
|
<body>
|
|
<table width="100%" height="48" border="0" background="theme/bkd2.gif" cellspacing="2">
|
|
<tr>
|
|
<td width="10">
|
|
</td>
|
|
<td width="85%">
|
|
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Embedding with Boost.Python</b></font>
|
|
</td>
|
|
<td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" align="right" border="0"></a></td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<table border="0">
|
|
<tr>
|
|
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
|
<td width="30"><a href="embedding_basics.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
|
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
|
|
</tr>
|
|
</table>
|
|
<a name="boost_python_to_the_rescue"></a><h2>Boost.Python to the rescue</h2><p>
|
|
Now we get to the good news. If you don't want to do all the error prone reference counting yourself, you can let Boost.Python do all the work. First include <tt><boost/python.hpp></tt> instead of <tt>"Python.h"</tt> and link to <tt>boost_python.lib</tt> (or <tt>boost_python_debug.lib</tt>) instead of <tt>pythonXY.lib</tt>. Then all we really need to do is replace every PyObject* with <a href="../../v2/handle.html">
|
|
handle</a><> and we can remove all the <a href="http://www.python.org/doc/current/api/countingRefs.html#l2h-65">
|
|
Py_XINCREF</a>s and <a href="http://www.python.org/doc/current/api/countingRefs.html#l2h-67">
|
|
Py_XDECREF</a>s! All the reference counting will be done automagically through the power of the <a href="http://sourceforge.net/docman/display_doc.php?docid=8673&group_id=9028">
|
|
Resource Acquisition Is Initialization</a> idiom. </p>
|
|
<p>
|
|
We still need a way to differentiate between new and borrowed references though. Luckily, this is pretty straightforward using the <a href="../../v2/handle.html#borrowed-spec">
|
|
borrowed</a> function. Let's rewrite the example to run Python code from a string to use <a href="../../v2/handle.html">
|
|
handle</a>s:</p>
|
|
<code><pre>
|
|
<span class=comment>// Get the __main__ module namespace
|
|
</span><span class=identifier>handle</span><span class=special><> </span><span class=identifier>main_module</span><span class=special>( </span><span class=identifier>borrowed</span><span class=special>(</span><span class=identifier>PyImport_AddModule</span><span class=special>(</span><span class=string>"__main__"</span><span class=special>)) </span><span class=special>);
|
|
</span><span class=identifier>handle</span><span class=special><> </span><span class=identifier>main_namespace</span><span class=special>( </span><span class=identifier>borrowed</span><span class=special>(</span><span class=identifier>PyModule_GetDict</span><span class=special>(</span><span class=identifier>main_module</span><span class=special>)) </span><span class=special>);
|
|
</span><span class=comment>// Run a single Python expression and retrieve the result
|
|
</span><span class=identifier>handle</span><span class=special><> </span><span class=identifier>result</span><span class=special>( </span><span class=identifier>PyRun_String</span><span class=special>(</span><span class=string>"1 + 1"</span><span class=special>,
|
|
</span><span class=identifier>Py_eval_input</span><span class=special>, </span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>get</span><span class=special>(), </span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>get</span><span class=special>()) </span><span class=special>);
|
|
</span><span class=special>... </span><span class=comment>// Use the result
|
|
</span></pre></code>
|
|
<p>
|
|
The <a href="../../v2/handle.html#handle-spec-observers">
|
|
get</a>() member function used here returns the raw PyObject* that is held by the <a href="../../v2/handle.html">
|
|
handle</a>.</p>
|
|
<a name="boost_python_modules_in_an_embedded_program"></a><h2>Boost.Python modules in an embedded program</h2><p>
|
|
Now that we know how to call Python code from C++ and C++ code from Python, how about doing both at the same time? Sometimes you might want to call Python code from C++ and have that Python code call C++ code again. </p>
|
|
<p>
|
|
If you built your Boost.Python module and put it in the proper directory, you can just use it in your embedded Python code as you would in a standalone Python program. The embedded interpreter will be able to find your module just as the standalone interpreter would.</p>
|
|
<p>
|
|
However, you can also define the Boost.Python module in the same program that embeds the Python interpreter. Then you won't have to build the module seperately and place it in the proper directory. This also prevents others from using your module in their own Python code. (Unless they start taking your executable apart that is. <img src="theme/smiley.gif"></img>) </p>
|
|
<p>
|
|
Doing this is relatively straightforward. You just define your Boost.Python module as usual and use the basic embedding steps described earlier. However, before calling <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652">
|
|
Py_Initialize</a> you call <a href="http://www.python.org/doc/current/api/importing.html#l2h-137">
|
|
PyImport_AppendInittab</a> first. </p>
|
|
<p>
|
|
This function takes the name and <a href="../../v2/module.html#BOOST_PYTHON_MODULE-spec">
|
|
initialization function</a> of your module as parameters and adds the module to the interpreter's list of builtin modules. So when the Python interpreter comes across an import statement, it will find the module in its list of builtin modules instead of (unsuccessfully) searching for it in the Python directory.</p>
|
|
<p>
|
|
Your program will look something like this:</p>
|
|
<code><pre>
|
|
<span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>my_module</span><span class=special>)
|
|
</span><span class=special>{
|
|
</span><span class=special>...
|
|
</span><span class=special>}
|
|
</span><span class=special>...
|
|
</span><span class=identifier>PyImport_AppendInittab</span><span class=special>(</span><span class=string>"my_module"</span><span class=special>, </span><span class=identifier>initmy_module</span><span class=special>);
|
|
</span><span class=identifier>Py_Initialize</span><span class=special>();
|
|
</span><span class=special>...
|
|
</span></pre></code>
|
|
<table width="80%" border="0" align="center">
|
|
<tr>
|
|
<td class="note_box">
|
|
<img src="theme/alert.gif"></img> <b>Warning</b><br><br>
|
|
|
|
When creating Boost.Python modules in the same program that embeds interpreter, you must <b><i>not</i></b> call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656">
|
|
Py_Finalize</a>. Boost.Python keeps some PyObject references alive in global data structures, and when those go out of scope after interpreter finalization, Python crashes. This will be fixed in the future. Stay tuned.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<a name="additional_reading"></a><h2>Additional reading</h2><p>
|
|
A more elaborate example showing these techniques is located at <a href="../../../test/embedding.cpp">
|
|
/libs/python/test/embedding.cpp</a>. </p>
|
|
<table border="0">
|
|
<tr>
|
|
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
|
<td width="30"><a href="embedding_basics.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
|
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
|
|
</tr>
|
|
</table>
|
|
<br>
|
|
<hr size="1"><p class="copyright">Copyright © 2002 Dirk Gerrits <br><br>
|
|
<font size="2">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. </font> </p>
|
|
</body>
|
|
</html>
|