|
| 1 | +<html> |
| 2 | +<head> |
| 3 | +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| 4 | +<link rel="stylesheet" type="text/css" href="../boost.css"> |
| 5 | +<title>Boost.Python - <register_ptr_to_python.hpp></title> |
| 6 | +</head> |
| 7 | +<body link="#0000ff" vlink="#800080"> |
| 8 | +<table border="0" cellpadding="7" cellspacing="0" width="100%" summary= |
| 9 | + "header"> |
| 10 | + <tr> |
| 11 | + <td valign="top" width="300"> |
| 12 | + <h3><a href="../../../../index.htm"><img height="86" width="277" alt= |
| 13 | + "C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3> |
| 14 | + </td> |
| 15 | + <td valign="top"> |
| 16 | + <h1 align="center"><a href="../index.html">Boost.Python</a></h1> |
| 17 | + <h2 align="center">Header <register_ptr_to_python.hpp></h2> |
| 18 | + </td> |
| 19 | + </tr> |
| 20 | +</table> |
| 21 | +<hr> |
| 22 | +<h2>Contents</h2> |
| 23 | +<dl class="page-index"> |
| 24 | + <dt><a href="#introduction">Introduction</a></dt> |
| 25 | + <dt><a href="#functions">Functions</a></dt> |
| 26 | + <dl class="page-index"> |
| 27 | + <dt><a href="#register_ptr_to_python-spec">register_ptr_to_python</a></dt> |
| 28 | + </dl> |
| 29 | + |
| 30 | + <dt><a href="#examples">Example(s)</a></dt> |
| 31 | + |
| 32 | +</dl> |
| 33 | +<hr> |
| 34 | +<h2><a name="introduction"></a>Introduction</h2> |
| 35 | +<p> |
| 36 | + <code><boost/python/converter/register_ptr_to_python.hpp></code> |
| 37 | + supplies <code>register_ptr_to_python</code>, a function template |
| 38 | + which registers a conversion for smart pointers to Python. The |
| 39 | + resulting Python object holds a copy of the converted smart pointer, |
| 40 | + but behaves as though it were a wrapped copy of the pointee. If |
| 41 | + the pointee type has virtual functions and the class representing |
| 42 | + its dynamic (most-derived) type has been wrapped, the Python object |
| 43 | + will be an instance of the wrapper for the most-derived type. More than |
| 44 | + one smart pointer type for a pointee's class can be registered. |
| 45 | +</p> |
| 46 | +<p> |
| 47 | + Note that in order to convert a Python <code>X</code> object to a |
| 48 | + <code>smart_ptr<X>&</code> (non-const reference), the embedded C++ |
| 49 | + object must be held by <code>smart_ptr<X></code>, and that when wrapped |
| 50 | + objects are created by calling the constructor from Python, how they are held |
| 51 | + is determined by the <code>HeldType</code> parameter to class_<...> |
| 52 | + instances. |
| 53 | +</p> |
| 54 | + |
| 55 | +<h2><a name="functions"></a>Functions</h2> |
| 56 | +<pre> |
| 57 | +<a name="register_ptr_to_python-spec">template <class P> |
| 58 | +void register_ptr_to_python() |
| 59 | +</pre> |
| 60 | +<dl class="function-semantics"> |
| 61 | + <dt><b>Requires:</b> <code>P</code> is the type of the smart pointer, |
| 62 | + for example <code>smart_ptr<X></code>. |
| 63 | + </dt> |
| 64 | + <dt><b>Effects:</b> Allows conversions to-python of <code>smart_ptr<X></code> |
| 65 | + instances. |
| 66 | + </dt> |
| 67 | +</dl> |
| 68 | + |
| 69 | +<h2><a name="examples"></a>Example(s)</h2> |
| 70 | + |
| 71 | +<h3>C++ Wrapper Code</h3> |
| 72 | + |
| 73 | +Here is an example of a module that contains a class <code>A</code> with |
| 74 | +virtual functions and some functions that work with |
| 75 | +<code>boost::shared_ptr<A></code>. |
| 76 | + |
| 77 | +<pre> |
| 78 | +struct A |
| 79 | +{ |
| 80 | + virtual int f() { return 0; } |
| 81 | +}; |
| 82 | + |
| 83 | +shared_ptr<A> New() { return shared_ptr<A>( new A() ); } |
| 84 | + |
| 85 | +int Ok( const shared_ptr<A>& a ) { return a->f(); } |
| 86 | + |
| 87 | +int Fail( shared_ptr<A>& a ) { return a->f(); } |
| 88 | + |
| 89 | +struct A_Wrapper: A |
| 90 | +{ |
| 91 | + A_Wrapper(PyObject* self_): self(self_) {} |
| 92 | + int f() { return call_method<int>(self, "f"); } |
| 93 | + int default_f() { return A::f(); } |
| 94 | + PyObject* self; |
| 95 | +}; |
| 96 | + |
| 97 | +BOOST_PYTHON_MODULE(register_ptr) |
| 98 | +{ |
| 99 | + class_<A, A_Wrapper>("A") |
| 100 | + .def("f", &A::f, &A_Wrapper::default_f) |
| 101 | + ; |
| 102 | + |
| 103 | + def("New", &New); |
| 104 | + def("Ok", &Call); |
| 105 | + def("Fail", &Fail); |
| 106 | + |
| 107 | + register_ptr_to_python< shared_ptr<A> >(); |
| 108 | +} |
| 109 | +</pre> |
| 110 | + |
| 111 | +<h3>Python Code</h3> |
| 112 | + |
| 113 | +<pre> |
| 114 | +>>> from register_ptr import * |
| 115 | +>>> a = A() |
| 116 | +>>> Ok(a) # ok, passed as shared_ptr<A> |
| 117 | +0 |
| 118 | +>>> Fail(a) # passed as shared_ptr<A>&, and was created in Python! |
| 119 | +Traceback (most recent call last): |
| 120 | + File "<stdin>", line 1, in ? |
| 121 | +TypeError: bad argument type for built-in operation |
| 122 | +>>> |
| 123 | +>>> na = New() # now "na" is actually a shared_ptr<A> |
| 124 | +>>> Ok(a) |
| 125 | +0 |
| 126 | +>>> Fail(a) |
| 127 | +0 |
| 128 | +>>> |
| 129 | +</pre> |
| 130 | + |
| 131 | +If <code>shared_ptr<A></code> is registered as follows: |
| 132 | + |
| 133 | +<pre> |
| 134 | + class_<A, A_Wrapper, shared_ptr<A> >("A") |
| 135 | + .def("f", &A::f, &A_Wrapper::default_f) |
| 136 | + ; |
| 137 | +</pre> |
| 138 | + |
| 139 | +There will be an error when trying to convert <code>shared_ptr<A></code> to |
| 140 | +<code>shared_ptr<A_Wrapper></code>: |
| 141 | + |
| 142 | +<pre> |
| 143 | +>>> a = New() |
| 144 | +Traceback (most recent call last): |
| 145 | +File "<stdin>", line 1, in ? |
| 146 | +TypeError: No to_python (by-value) converter found for C++ type: class boost::shared_ptr<struct A> |
| 147 | +>>> |
| 148 | +</pre> |
| 149 | + |
| 150 | +<p>Revised |
| 151 | + <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan --> |
| 152 | + 24 Jun, 2003 |
| 153 | + <!--webbot bot="Timestamp" endspan i-checksum="39359" --> |
| 154 | +</p> |
| 155 | +<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a> |
| 156 | + 2002. All Rights Reserved.</i></p> |
| 157 | +</body> |
| 158 | +</html> |
| 159 | + |
| 160 | + |
0 commit comments