1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Chapter 8. Topics</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 Reference Manual"> 8<link rel="up" href="index.html" title="Boost.Python Reference Manual"> 9<link rel="prev" href="utility_and_infrastructure/boost_python_ssize_t_hpp.html" title="boost/python/ssize_t.hpp"> 10<link rel="next" href="topics/pickle_support.html" title="Pickle support"> 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="utility_and_infrastructure/boost_python_ssize_t_hpp.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="topics/pickle_support.html"><img src="../images/next.png" alt="Next"></a> 17</div> 18<div class="chapter"> 19<div class="titlepage"><div><div><h1 class="title"> 20<a name="topics"></a>Chapter 8. Topics</h1></div></div></div> 21<div class="toc"> 22<p><b>Table of Contents</b></p> 23<dl class="toc"> 24<dt><span class="section"><a href="topics.html#topics.calling_python_functions_and_met">Calling Python 25 Functions and Methods</a></span></dt> 26<dd><dl> 27<dt><span class="section"><a href="topics.html#topics.calling_python_functions_and_met.introduction">Introduction</a></span></dt> 28<dt><span class="section"><a href="topics.html#topics.calling_python_functions_and_met.argument_handling">Argument 29 Handling</a></span></dt> 30<dt><span class="section"><a href="topics.html#topics.calling_python_functions_and_met.result_handling">Result 31 Handling</a></span></dt> 32<dt><span class="section"><a href="topics.html#topics.calling_python_functions_and_met.rationale">Rationale</a></span></dt> 33</dl></dd> 34<dt><span class="section"><a href="topics/pickle_support.html">Pickle support</a></span></dt> 35<dd><dl> 36<dt><span class="section"><a href="topics/pickle_support.html#topics.pickle_support.introduction">Introduction</a></span></dt> 37<dt><span class="section"><a href="topics/pickle_support.html#topics.pickle_support.the_pickle_interface">The Pickle 38 Interface</a></span></dt> 39<dt><span class="section"><a href="topics/pickle_support.html#topics.pickle_support.example">Example</a></span></dt> 40<dt><span class="section"><a href="topics/pickle_support.html#topics.pickle_support.pitfall_and_safety_guard">Pitfall 41 and Safety Guard</a></span></dt> 42<dt><span class="section"><a href="topics/pickle_support.html#topics.pickle_support.practical_advice">Practical Advice</a></span></dt> 43<dt><span class="section"><a href="topics/pickle_support.html#topics.pickle_support.light_weight_alternative_pickle_">Light-weight 44 alternative: pickle support implemented in Python</a></span></dt> 45</dl></dd> 46<dt><span class="section"><a href="topics/indexing_support.html">Indexing support</a></span></dt> 47<dd><dl> 48<dt><span class="section"><a href="topics/indexing_support.html#topics.indexing_support.introduction">Introduction</a></span></dt> 49<dt><span class="section"><a href="topics/indexing_support.html#topics.indexing_support.the_indexing_interface">The 50 Indexing Interface</a></span></dt> 51<dt><span class="section"><a href="topics/indexing_support.html#topics.indexing_support.index_suite_sub_classes">index_suite 52 sub-classes</a></span></dt> 53<dt><span class="section"><a href="topics/indexing_support.html#topics.indexing_support.indexing_suite_class"><code class="computeroutput"><span class="identifier">indexing_suite</span></code> class</a></span></dt> 54<dt><span class="section"><a href="topics/indexing_support.html#topics.indexing_support.class_vector_indexing_suite">class 55 <code class="computeroutput"><span class="identifier">vector_indexing_suite</span></code></a></span></dt> 56<dt><span class="section"><a href="topics/indexing_support.html#topics.indexing_support.class_map_indexing_suite">class 57 <code class="computeroutput"><span class="identifier">map_indexing_suite</span></code></a></span></dt> 58</dl></dd> 59</dl> 60</div> 61<div class="section"> 62<div class="titlepage"><div><div><h2 class="title" style="clear: both"> 63<a name="topics.calling_python_functions_and_met"></a><a class="link" href="topics.html#topics.calling_python_functions_and_met" title="Calling Python Functions and Methods">Calling Python 64 Functions and Methods</a> 65</h2></div></div></div> 66<div class="toc"><dl class="toc"> 67<dt><span class="section"><a href="topics.html#topics.calling_python_functions_and_met.introduction">Introduction</a></span></dt> 68<dt><span class="section"><a href="topics.html#topics.calling_python_functions_and_met.argument_handling">Argument 69 Handling</a></span></dt> 70<dt><span class="section"><a href="topics.html#topics.calling_python_functions_and_met.result_handling">Result 71 Handling</a></span></dt> 72<dt><span class="section"><a href="topics.html#topics.calling_python_functions_and_met.rationale">Rationale</a></span></dt> 73</dl></div> 74<div class="section"> 75<div class="titlepage"><div><div><h3 class="title"> 76<a name="topics.calling_python_functions_and_met.introduction"></a><a class="link" href="topics.html#topics.calling_python_functions_and_met.introduction" title="Introduction">Introduction</a> 77</h3></div></div></div> 78<p> 79 The simplest way to call a Python function from C++, given an <a class="link" href="object_wrappers/boost_python_object_hpp.html#object_wrappers.boost_python_object_hpp.class_object" title="Class object"><code class="computeroutput"><span class="identifier">object</span></code></a> instance f holding the 80 function, is simply to invoke its function call operator. 81 </p> 82<pre class="programlisting"><span class="identifier">f</span><span class="special">(</span><span class="string">"tea"</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">2</span><span class="special">)</span> <span class="comment">// In Python: f('tea', 4, 2)</span></pre> 83<p> 84 And of course, a method of an <a class="link" href="object_wrappers/boost_python_object_hpp.html#object_wrappers.boost_python_object_hpp.class_object" title="Class object"><code class="computeroutput"><span class="identifier">object</span></code></a> instance <code class="computeroutput"><span class="identifier">x</span></code> can be invoked by using the function-call 85 operator of the corresponding attribute: 86 </p> 87<pre class="programlisting"><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"tea"</span><span class="special">)(</span><span class="number">4</span><span class="special">,</span> <span class="number">2</span><span class="special">);</span> <span class="comment">// In Python: x.tea(4, 2)</span></pre> 88<p> 89 If you don't have an <a class="link" href="object_wrappers/boost_python_object_hpp.html#object_wrappers.boost_python_object_hpp.class_object" title="Class object"><code class="computeroutput"><span class="identifier">object</span></code></a> instance, <code class="computeroutput"><span class="identifier">Boost</span><span class="special">.</span><span class="identifier">Python</span></code> provides two families of function 90 templates, <a class="link" href="function_invocation_and_creation/boost_python_call_hpp.html#function_invocation_and_creation.boost_python_call_hpp.function_call" title="Function call"><code class="computeroutput"><span class="identifier">call</span></code></a> and <a class="link" href="function_invocation_and_creation/boost_python_call_method_hpp.html#function_invocation_and_creation.boost_python_call_method_hpp.function_call_method" title="Function call_method"><code class="computeroutput"><span class="identifier">call_method</span></code></a>, for invoking Python 91 functions and methods respectively on <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code>s. The interface for calling a Python function 92 object (or any Python callable object) looks like: 93 </p> 94<pre class="programlisting"><span class="identifier">call</span><span class="special"><</span><span class="identifier">ResultType</span><span class="special">>(</span><span class="identifier">callable_object</span><span class="special">,</span> <span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">...</span> <span class="identifier">aN</span><span class="special">);</span></pre> 95<p> 96 Calling a method of a Python object is similarly easy: 97 </p> 98<pre class="programlisting"><span class="identifier">call_method</span><span class="special"><</span><span class="identifier">ResultType</span><span class="special">>(</span><span class="identifier">self_object</span><span class="special">,</span> <span class="string">"method-name"</span><span class="special">,</span> <span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">...</span> <span class="identifier">aN</span><span class="special">);</span></pre> 99<p> 100 This comparitively low-level interface is the one you'll use when implementing 101 C++ virtual functions that can be overridden in Python. 102 </p> 103</div> 104<div class="section"> 105<div class="titlepage"><div><div><h3 class="title"> 106<a name="topics.calling_python_functions_and_met.argument_handling"></a><a class="link" href="topics.html#topics.calling_python_functions_and_met.argument_handling" title="Argument Handling">Argument 107 Handling</a> 108</h3></div></div></div> 109<p> 110 Arguments are converted to Python according to their type. By default, 111 the arguments <code class="computeroutput"><span class="identifier">a1</span><span class="special">...</span><span class="identifier">aN</span></code> are copied into new Python objects, 112 but this behavior can be overridden by the use of <a class="link" href="function_invocation_and_creation/boost_python_ptr_hpp.html#function_invocation_and_creation.boost_python_ptr_hpp.functions" title="Functions"><code class="computeroutput"><span class="identifier">ptr</span><span class="special">()</span></code></a> 113 and <code class="computeroutput"><span class="identifier">ref</span><span class="special">()</span></code>: 114 </p> 115<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">X</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span> 116<span class="special">{</span> 117 <span class="special">...</span> 118<span class="special">};</span> 119 120<span class="keyword">void</span> <span class="identifier">apply</span><span class="special">(</span><span class="identifier">PyObject</span><span class="special">*</span> <span class="identifier">callable</span><span class="special">,</span> <span class="identifier">X</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> 121<span class="special">{</span> 122 <span class="comment">// Invoke callable, passing a Python object which holds a reference to x</span> 123 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">call</span><span class="special"><</span><span class="keyword">void</span><span class="special">>(</span><span class="identifier">callable</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">x</span><span class="special">));</span> 124<span class="special">}</span> 125</pre> 126<p> 127 In the table below, x denotes the actual argument object and cv denotes 128 an optional cv-qualification: "const", "volatile", 129 or "const volatile". 130 </p> 131<div class="informaltable"><table class="table"> 132<colgroup> 133<col> 134<col> 135</colgroup> 136<thead><tr> 137<th> 138 <p> 139 Argument Type 140 </p> 141 </th> 142<th> 143 <p> 144 Behavior 145 </p> 146 </th> 147</tr></thead> 148<tbody> 149<tr> 150<td> 151 <p> 152 <code class="computeroutput"><span class="identifier">T</span> <span class="identifier">cv</span> 153 <span class="special">&</span></code> <code class="computeroutput"><span class="identifier">T</span> 154 <span class="identifier">cv</span></code> 155 </p> 156 </td> 157<td> 158 <p> 159 The Python argument is created by the same means used for the 160 return value of a wrapped C++ function returning T. When T is 161 a class type, that normally means *x is copy-constructed into 162 the new Python object. 163 </p> 164 </td> 165</tr> 166<tr> 167<td> 168 <p> 169 T* 170 </p> 171 </td> 172<td> 173 <p> 174 If x == 0, the Python argument will be None. Otherwise, the Python 175 argument is created by the same means used for the return value 176 of a wrapped C++ function returning T. When T is a class type, 177 that normally means *x is copy-constructed into the new Python 178 object. 179 </p> 180 </td> 181</tr> 182<tr> 183<td> 184 <p> 185 boost::reference_wrapper<T> 186 </p> 187 </td> 188<td> 189 <p> 190 The Python argument contains a pointer to, rather than a copy 191 of, x.get(). Note: failure to ensure that no Python code holds 192 a reference to the resulting object beyond the lifetime of *x.get() 193 may result in a crash! 194 </p> 195 </td> 196</tr> 197<tr> 198<td> 199 <p> 200 pointer_wrapper<T> 201 </p> 202 </td> 203<td> 204 <p> 205 If x.get() == 0, the Python argument will be None. Otherwise, 206 the Python argument contains a pointer to, rather than a copy 207 of, *x.get(). Note: failure to ensure that no Python code holds 208 a reference to the resulting object beyond the lifetime of *x.get() 209 may result in a crash! 210 </p> 211 </td> 212</tr> 213</tbody> 214</table></div> 215</div> 216<div class="section"> 217<div class="titlepage"><div><div><h3 class="title"> 218<a name="topics.calling_python_functions_and_met.result_handling"></a><a class="link" href="topics.html#topics.calling_python_functions_and_met.result_handling" title="Result Handling">Result 219 Handling</a> 220</h3></div></div></div> 221<p> 222 In general, <code class="computeroutput"><span class="identifier">call</span><span class="special"><</span><span class="identifier">ResultType</span><span class="special">>()</span></code> 223 and call_method<ResultType>() return ResultType by exploiting all 224 lvalue and rvalue from_python converters registered for ResultType and 225 returning a copy of the result. However, when ResultType is a pointer or 226 reference type, Boost.Python searches only for lvalue converters. To prevent 227 dangling pointers and references, an exception will be thrown if the Python 228 result object has only a single reference count. 229 </p> 230</div> 231<div class="section"> 232<div class="titlepage"><div><div><h3 class="title"> 233<a name="topics.calling_python_functions_and_met.rationale"></a><a class="link" href="topics.html#topics.calling_python_functions_and_met.rationale" title="Rationale">Rationale</a> 234</h3></div></div></div> 235<p> 236 In general, to get Python arguments corresponding to a1...aN, a new Python 237 object must be created for each one; should the C++ object be copied into 238 that Python object, or should the Python object simply hold a reference/pointer 239 to the C++ object? In general, the latter approach is unsafe, since the 240 called function may store a reference to the Python object somewhere. If 241 the Python object is used after the C++ object is destroyed, we'll crash 242 Python. 243 </p> 244<p> 245 In keeping with the philosophy that users on the Python side shouldn't 246 have to worry about crashing the interpreter, the default behavior is to 247 copy the C++ object, and to allow a non-copying behavior only if the user 248 writes boost::ref(a1) instead of a1 directly. At least this way, the user 249 doesn't get dangerous behavior "by accident". It's also worth 250 noting that the non-copying ("by-reference") behavior is in general 251 only available for class types, and will fail at runtime with a Python 252 exception if used otherwise[1]. 253 </p> 254<p> 255 However, pointer types present a problem: one approach is to refuse to 256 compile if any aN has pointer type: after all, a user can always pass *aN 257 to pass "by-value" or ref(*aN) to indicate a pass-by-reference 258 behavior. However, this creates a problem for the expected null pointer 259 to None conversion: it's illegal to dereference a null pointer value. 260 </p> 261<p> 262 The compromise I've settled on is this: 263 </p> 264<div class="orderedlist"><ol class="orderedlist" type="1"> 265<li class="listitem"> 266 The default behavior is pass-by-value. If you pass a non-null pointer, 267 the pointee is copied into a new Python object; otherwise the corresponding 268 Python argument will be None. 269 </li> 270<li class="listitem"> 271 if you want by-reference behavior, use ptr(aN) if aN is a pointer and 272 ref(aN) otherwise. If a null pointer is passed to ptr(aN), the corresponding 273 Python argument will be None. 274 </li> 275</ol></div> 276<p> 277 As for results, we have a similar problem: if ResultType is allowed to 278 be a pointer or reference type, the lifetime of the object it refers to 279 is probably being managed by a Python object. When that Python object is 280 destroyed, our pointer dangles. The problem is particularly bad when the 281 ResultType is char const* - the corresponding Python String object is typically 282 uniquely-referenced, meaning that the pointer dangles as soon as call<char 283 const*>(...) returns. 284 </p> 285<p> 286 The old Boost.Python v1 deals with this issue by refusing to compile any 287 uses of call<char const*>(), but this goes both too far and not far 288 enough. It goes too far because there are cases where the owning Python 289 string object survives beyond the call (just for instance, when it's the 290 name of a Python class), and it goes not far enough because we might just 291 as well have the same problem with a returned pointer or reference of any 292 other type. 293 </p> 294<p> 295 In Boost.Python this is dealt with by: 296 </p> 297<div class="orderedlist"><ol class="orderedlist" type="1"> 298<li class="listitem"> 299 lifting the compile-time restriction on <code class="computeroutput"><span class="keyword">char</span> 300 <span class="keyword">const</span> <span class="special">*</span></code> 301 callback returns 302 </li> 303<li class="listitem"> 304 detecting the case when the reference count on the result Python object 305 is 1 and throwing an exception inside of <code class="computeroutput"><span class="identifier">call</span><span class="special"><</span><span class="identifier">U</span><span class="special">>(...)</span></code> when <code class="computeroutput"><span class="identifier">U</span></code> 306 is a pointer or reference type. 307 </li> 308</ol></div> 309<p> 310 This should be acceptably safe because users have to explicitly specify 311 a pointer/reference for <code class="computeroutput"><span class="identifier">U</span></code> 312 in <code class="computeroutput"><span class="identifier">call</span><span class="special"><</span><span class="identifier">U</span><span class="special">></span></code>, 313 and they will be protected against dangles at runtime, at least long enough 314 to get out of the <code class="computeroutput"><span class="identifier">call</span><span class="special"><</span><span class="identifier">U</span><span class="special">>(...)</span></code> invocation. 315 </p> 316</div> 317</div> 318</div> 319<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 320<td align="left"></td> 321<td align="right"><div class="copyright-footer">Copyright © 2002-2005, 2015 David Abrahams, Stefan Seefeld<p> 322 Distributed under the Boost Software License, Version 1.0. (See accompanying 323 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> 324 </p> 325</div></td> 326</tr></table> 327<hr> 328<div class="spirit-nav"> 329<a accesskey="p" href="utility_and_infrastructure/boost_python_ssize_t_hpp.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="topics/pickle_support.html"><img src="../images/next.png" alt="Next"></a> 330</div> 331</body> 332</html> 333