253 lines
11 KiB
HTML
253 lines
11 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
|
|
<html>
|
|
<head>
|
|
<meta name="generator" content=
|
|
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
<link rel="stylesheet" type="text/css" href="../boost.css">
|
|
|
|
<title>Boost.Python - Calling Python Functions and Methods</title>
|
|
</head>
|
|
|
|
<body link="#0000ff" vlink="#800080">
|
|
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
|
"header">
|
|
<tr>
|
|
<td valign="top" width="300">
|
|
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
|
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
|
</td>
|
|
|
|
<td valign="top">
|
|
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
|
|
|
<h2 align="center">Calling Python Functions and Methods</h2>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<hr>
|
|
|
|
<h2>Contents</h2>
|
|
|
|
<dl class="page-index">
|
|
<dt><a href="#introduction">Introduction</a></dt>
|
|
|
|
<dt><a href="#argument_handling">Argument Handling</a></dt>
|
|
|
|
<dt><a href="#result_handling">Result Handling</a></dt>
|
|
|
|
<dt><a href="#result_handling">Rationale</a></dt>
|
|
</dl>
|
|
<hr>
|
|
|
|
<h2><a name="introduction">Introduction</a></h2>
|
|
The simplest way to call a Python function from C++, given an <code><a
|
|
href="object.html#object-spec">object</a></code> instance <code>f</code>
|
|
holding the function, is simply to invoke its function call operator.
|
|
<pre>
|
|
f("tea", 4, 2) // In Python: f('tea', 4, 2)
|
|
</pre>
|
|
And of course, a method of an <code><a href=
|
|
"object.html#object-spec">object</a></code> instance <code>x</code> can
|
|
be invoked by using the function-call operator of the corresponding
|
|
attribute:
|
|
<pre>
|
|
x.attr("tea")(4, 2); // In Python: x.tea(4, 2)
|
|
</pre>
|
|
|
|
<p>If you don't have an <code>object</code> instance, Boost.Python
|
|
provides two families of function templates, <code><a href=
|
|
"call.html#call-spec">call</a></code> and <code><a href=
|
|
"call_method.html#call_method-spec">call_method</a></code>, for invoking
|
|
Python functions and methods respectively on <code>PyObject*</code>s. The
|
|
interface for calling a Python function object (or any Python callable
|
|
object) looks like:</p>
|
|
<pre>
|
|
call<ResultType>(callable_object, a1, a2... a<i>N</i>);
|
|
</pre>
|
|
Calling a method of a Python object is similarly easy:
|
|
<pre>
|
|
call_method<ResultType>(self_object, "<i>method-name</i>", a1, a2... a<i>N</i>);
|
|
</pre>
|
|
This comparitively low-level interface is the one you'll use when
|
|
implementing C++ virtual functions that can be overridden in Python.
|
|
|
|
<h2><a name="argument_handling">Argument Handling</a></h2>
|
|
|
|
<p>Arguments are converted to Python according to their type. By default,
|
|
the arguments <code>a1</code>...<code>a<i>N</i></code> are copied into
|
|
new Python objects, but this behavior can be overridden by the use of
|
|
<code><a href="ptr.html#ptr-spec">ptr()</a></code> and <a href=
|
|
"../../../bind/ref.html#reference_wrapper">ref()</a>:</p>
|
|
<pre>
|
|
class X : boost::noncopyable
|
|
{
|
|
...
|
|
};
|
|
|
|
void apply(PyObject* callable, X& x)
|
|
{
|
|
// Invoke callable, passing a Python object which holds a reference to x
|
|
boost::python::call<void>(callable, boost::ref(x));
|
|
}
|
|
</pre>
|
|
In the table below, <code><b>x</b></code> denotes the actual argument
|
|
object and <code><b>cv</b></code> denotes an optional
|
|
<i>cv-qualification</i>: "<code>const</code>", "<code>volatile</code>",
|
|
or "<code>const volatile</code>".
|
|
|
|
<table border="1" summary="class_ template parameters">
|
|
<tr>
|
|
<th>Argument Type</th>
|
|
|
|
<th>Behavior</th>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>T cv&</code><br>
|
|
<code>T cv</code></td>
|
|
|
|
<td>The Python argument is created by the same means used for the
|
|
return value of a wrapped C++ function returning <code>T</code>. When
|
|
<code>T</code> is a class type, that normally means <code>*x</code>
|
|
is copy-constructed into the new Python object.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code>T*</code></td>
|
|
|
|
<td>If <code>x == 0</code>, the Python argument will be
|
|
<code><a href=
|
|
"http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
|
|
Otherwise, the Python argument is created by the same means used for
|
|
the return value of a wrapped C++ function returning <code>T</code>.
|
|
When <code>T</code> is a class type, that normally means
|
|
<code>*x</code> is copy-constructed into the new Python object.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code><a href=
|
|
"../../../bind/ref.html#reference_wrapper">boost::reference_wrapper</a><T></code></td>
|
|
|
|
<td>The Python argument contains a pointer to, rather than a copy of,
|
|
<code>x.get()</code>. Note: failure to ensure that no Python code
|
|
holds a reference to the resulting object beyond the lifetime of
|
|
<code>*x.get()</code> <b>may result in a crash!</b></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><code><a href=
|
|
"ptr.html#pointer_wrapper-spec">pointer_wrapper</a><T></code></td>
|
|
|
|
<td>If <code>x.get() == 0</code>, the Python argument will
|
|
be <code><a href=
|
|
"http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
|
|
Otherwise, the Python argument contains a pointer to, rather than a
|
|
copy of, <code>*x.get()</code>. Note: failure to ensure that no
|
|
Python code holds a reference to the resulting object beyond the
|
|
lifetime of <code>*x.get()</code> <b>may result in a crash!</b></td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h2><a name="result_handling">Result Handling</a></h2>
|
|
In general, <code>call<ResultType>()</code> and
|
|
<code>call_method<ResultType>()</code> return
|
|
<code>ResultType</code> by exploiting all lvalue and rvalue
|
|
<code>from_python</code> converters registered for ResultType and
|
|
returning a copy of the result. However, when <code>ResultType</code> is
|
|
a pointer or reference type, Boost.Python searches only for lvalue
|
|
converters. To prevent dangling pointers and references, an exception
|
|
will be thrown if the Python result object has only a single reference
|
|
count.
|
|
|
|
<h2><a name="rationale">Rationale</a></h2>
|
|
In general, to get Python arguments corresponding to
|
|
<code>a1</code>...<code>a<i>N</i></code>, a new Python object must be
|
|
created for each one; should the C++ object be copied into that Python
|
|
object, or should the Python object simply hold a reference/pointer to
|
|
the C++ object? In general, the latter approach is unsafe, since the
|
|
called function may store a reference to the Python object somewhere. If
|
|
the Python object is used after the C++ object is destroyed, we'll crash
|
|
Python.
|
|
|
|
<p>In keeping with the philosophy that users on the Python side shouldn't
|
|
have to worry about crashing the interpreter, the default behavior is to
|
|
copy the C++ object, and to allow a non-copying behavior only if the user
|
|
writes <code><a href="../../../bind/ref.html">boost::ref</a>(a1)</code>
|
|
instead of a1 directly. At least this way, the user doesn't get dangerous
|
|
behavior "by accident". It's also worth noting that the non-copying
|
|
("by-reference") behavior is in general only available for class types,
|
|
and will fail at runtime with a Python exception if used otherwise[<a
|
|
href="#1">1</a>].</p>
|
|
|
|
<p>However, pointer types present a problem: one approach is to refuse to
|
|
compile if any aN has pointer type: after all, a user can always pass
|
|
<code>*aN</code> to pass "by-value" or <code>ref(*aN)</code> to indicate
|
|
a pass-by-reference behavior. However, this creates a problem for the
|
|
expected null pointer to <code>None</code> conversion: it's illegal to
|
|
dereference a null pointer value.</p>
|
|
|
|
<p>The compromise I've settled on is this:</p>
|
|
|
|
<ol>
|
|
<li>The default behavior is pass-by-value. If you pass a non-null
|
|
pointer, the pointee is copied into a new Python object; otherwise the
|
|
corresponding Python argument will be None.</li>
|
|
|
|
<li>if you want by-reference behavior, use <code>ptr(aN)</code> if
|
|
<code>aN</code> is a pointer and <code>ref(aN)</code> otherwise. If a
|
|
null pointer is passed to <code>ptr(aN)</code>, the corresponding
|
|
Python argument will be <code>None</code>.</li>
|
|
</ol>
|
|
|
|
<p>As for results, we have a similar problem: if <code>ResultType</code>
|
|
is allowed to be a pointer or reference type, the lifetime of the object
|
|
it refers to is probably being managed by a Python object. When that
|
|
Python object is destroyed, our pointer dangles. The problem is
|
|
particularly bad when the <code>ResultType</code> is char const* - the
|
|
corresponding Python String object is typically uniquely-referenced,
|
|
meaning that the pointer dangles as soon as <code>call<char
|
|
const*>(...)</code> returns.</p>
|
|
|
|
<p>The old Boost.Python v1 deals with this issue by refusing to compile
|
|
any uses of <code>call<char const*>()</code>, but this goes both
|
|
too far and not far enough. It goes too far because there are cases where
|
|
the owning Python string object survives beyond the call (just for
|
|
instance, when it's the name of a Python class), and it goes not far
|
|
enough because we might just as well have the same problem with a
|
|
returned pointer or reference of any other type.</p>
|
|
|
|
<p>In Boost.Python v2 this is dealt with by:</p>
|
|
|
|
<ol>
|
|
<li>lifting the compile-time restriction on const char* callback
|
|
returns</li>
|
|
|
|
<li>detecting the case when the reference count on the result Python
|
|
object is 1 and throwing an exception inside of
|
|
<code>call<U>(...)</code> when <code>U</code> is a pointer or
|
|
reference type.</li>
|
|
</ol>
|
|
This should be acceptably safe because users have to explicitly specify a
|
|
pointer/reference for <code>U</code> in <code>call<U></code>, and
|
|
they will be protected against dangles at runtime, at least long enough
|
|
to get out of the <code>call<U>(...)</code> invocation.
|
|
<hr>
|
|
<a name="1">[1]</a> It would be possible to make it fail at compile-time
|
|
for non-class types such as int and char, but I'm not sure it's a good
|
|
idea to impose this restriction yet.
|
|
|
|
<p>Revised
|
|
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
|
13 November, 2002
|
|
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
|
</p>
|
|
|
|
<p><i>© Copyright <a href=
|
|
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
|
Reserved.</i></p>
|
|
</body>
|
|
</html>
|
|
|