| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| 2 | |
| 3 | <!-- Copyright Maximilian Matthe 2008. Distributed under the Boost --> |
| 4 | <!-- Software License, Version 1.0. (See accompanying --> |
| 5 | <!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> |
| 6 | <html> |
| 7 | <head> |
| 8 | <meta name="generator" content= |
| 9 | "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org"> |
| 10 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| 11 | <link rel="stylesheet" type="text/css" href="../boost.css"> |
| 12 | |
| 13 | <title>Boost.Python - |
| 14 | <boost/python/return_pointee_value.hpp></title> |
| 15 | </head> |
| 16 | |
| 17 | <body> |
| 18 | <table border="0" cellpadding="7" cellspacing="0" width="100%" summary= |
| 19 | "header"> |
| 20 | <tr> |
| 21 | <td valign="top" width="300"> |
| 22 | <h3><a href="../../../../index.htm"><img height="86" width="277" |
| 23 | alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3> |
| 24 | </td> |
| 25 | |
| 26 | <td valign="top"> |
| 27 | <h1 align="center"><a href="../index.html">Boost.Python</a></h1> |
| 28 | |
| 29 | <h2 align="center">Header |
| 30 | <boost/python/return_pointee_value.hpp></h2> |
| 31 | </td> |
| 32 | </tr> |
| 33 | </table> |
| 34 | <hr> |
| 35 | |
| 36 | <h2>Contents</h2> |
| 37 | |
| 38 | <dl class="page-index"> |
| 39 | <dt><a href="#classes">Classes</a></dt> |
| 40 | |
| 41 | <dd> |
| 42 | <dl class="page-index"> |
| 43 | <dt><a href="#return_pointee_value-spec">Class |
| 44 | <code>return_pointee_value</code></a></dt> |
| 45 | |
| 46 | <dd> |
| 47 | <dl class="page-index"> |
| 48 | <dt><a href="#return_pointee_value-spec-synopsis">Class |
| 49 | <code>return_pointee_value</code> synopsis</a></dt> |
| 50 | |
| 51 | <dt><a href= |
| 52 | "#return_pointee_value-spec-metafunctions">Class |
| 53 | <code>return_pointee_value</code> metafunctions</a></dt> |
| 54 | </dl> |
| 55 | </dd> |
| 56 | </dl> |
| 57 | </dd> |
| 58 | |
| 59 | <dt><a href="#examples">Example</a></dt> |
| 60 | </dl> |
| 61 | <hr> |
| 62 | |
| 63 | <h2><a name="classes"></a>Classes</h2> |
| 64 | |
| 65 | <h3><a name="return_pointee_value-spec"></a>Class |
| 66 | <code>return_pointee_value</code></h3> |
| 67 | |
| 68 | <p><code>return_pointee_value</code> is a model of <a href= |
| 69 | "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a> |
| 70 | which can be used to wrap C++ functions, that return a pointer to a C++ object. The |
| 71 | policy implements the following logic: |
| 72 | |
| 73 | <pre> |
| 74 | if return value is NULL pointer: |
| 75 | return None |
| 76 | else: |
| 77 | return bp::object( * return value ) |
| 78 | </pre> |
| 79 | |
| 80 | It passes the value of the pointee to python, thus the conversion for T is used, if |
| 81 | return value is of type T*.</p> |
| 82 | <p>This return_value_policy can therefore be used to return pointers to python, which |
| 83 | types are not known to boost.python but only a conversion for the pointees. Therefore this |
| 84 | policy should be used to return pointers to objects whose types were wrapped with |
| 85 | other tools, such as SWIG (see example).</p> |
| 86 | |
| 87 | <p><b>Please note:</b> This policy does not take ownership of the wrapped pointer. If the |
| 88 | object pointed to is deleted in C++, the python-object will become invalid too, if your custom |
| 89 | conversion depends on the original object.</p> |
| 90 | |
| 91 | <h4><a name="return_pointee_value-spec-synopsis"></a>Class |
| 92 | <code>return_pointee_value</code> synopsis</h4> |
| 93 | <pre> |
| 94 | namespace boost { namespace python |
| 95 | { |
| 96 | struct return_pointee_value |
| 97 | { |
| 98 | template <class T> struct apply; |
| 99 | }; |
| 100 | }} |
| 101 | </pre> |
| 102 | |
| 103 | <h4><a name="return_pointee_value-spec-metafunctions"></a>Class |
| 104 | <code>return_pointee_value</code> metafunctions</h4> |
| 105 | <pre> |
| 106 | template <class T> struct apply |
| 107 | </pre> |
| 108 | |
| 109 | <dl class="metafunction-semantics"> |
| 110 | <dt><b>Requires:</b> <code>T</code> is <code>U*</code>for some <code>U</code>.</dt> |
| 111 | |
| 112 | <dt><b>Returns:</b> <code>typedef <a href= |
| 113 | "to_python_indirect.html#to_python_indirect-spec">to_python_indirect</a><T,V> |
| 114 | type</code>, where <code>V</code> is a class whose |
| 115 | static <code>execute</code> function constructs a <code>boost::python::object</code> from |
| 116 | the dereferenced parameter of type <code>U*</code>.</dt> |
| 117 | </dl> |
| 118 | |
| 119 | <h2><a name="examples"></a>Example</h2> |
| 120 | <p><b>Example 1:</b> This example demonstrates the trivial use of <code>return_pointee_value</code> for returning |
| 121 | the value that the returned pointer points to: |
| 122 | </p> |
| 123 | <p>In C++:</p> |
| 124 | <pre> |
| 125 | #include <boost/python/module.hpp> |
| 126 | #include <boost/python/class.hpp> |
| 127 | #include <boost/python/return_pointee_value.hpp> |
| 128 | #include <boost/python/return_value_policy.hpp> |
| 129 | #inlcude <wxPython.h> |
| 130 | #include <utility> |
| 131 | |
| 132 | // The function which is going to be wrapped: |
| 133 | int* get_value() |
| 134 | { |
| 135 | static int val = 42; |
| 136 | return &val; |
| 137 | } |
| 138 | |
| 139 | // Function that returns a NULL-Pointer |
| 140 | int* get_null_value() |
| 141 | { |
| 142 | return NULL; |
| 143 | } |
| 144 | |
| 145 | // The wrapper |
| 146 | BOOST_PYTHON_MODULE(example) |
| 147 | { |
| 148 | using namespace boost::python; |
| 149 | // Wrap the functions with return_pointee_value |
| 150 | def("get_value", get_value, return_value_policy<return_pointee_value>()); |
| 151 | def("get_null_value", get_null_value, return_value_policy<return_pointee_value>()); |
| 152 | } |
| 153 | </pre> |
| 154 | <p>In Python:</p> |
| 155 | <pre> |
| 156 | >>> import example |
| 157 | >>> f = example.get_value() |
| 158 | >>> print f |
| 159 | 42 |
| 160 | >>> f = 5 |
| 161 | >>> print example.get_value() |
| 162 | 42 |
| 163 | >>> assert None is example.get_null_value() |
| 164 | </pre> |
| 165 | <p>Note that the value of the static C++-variable <code>val</code> is not changed when python assigns |
| 166 | a new value to <code>f</code>. This is caused by the logic of <code>return_pointee_value</code>: It returns |
| 167 | the <code>boost::python::object</code> which is constructed from <code>*val</code>.</p> |
| 168 | |
| 169 | <p><b>Example 2:</b> The following example uses return_pointee_value to return an object that is wrapped |
| 170 | with SWIG. I use the wxPython-API because it's easier to understand.</p> |
| 171 | |
| 172 | <p>In C++:</p> |
| 173 | <pre> |
| 174 | #include <boost/python/module.hpp> |
| 175 | #include <boost/python/class.hpp> |
| 176 | #include <boost/python/return_pointee_value.hpp> |
| 177 | #include <boost/python/return_value_policy.hpp> |
| 178 | #inlcude <wxPython.h> |
| 179 | #include <utility> |
| 180 | |
| 181 | // The following code assumes that there is set up a |
| 182 | // working wxWidgets application |
| 183 | |
| 184 | // Function to wrap: |
| 185 | wxWindow* getMainFrame() |
| 186 | { |
| 187 | return wxGetApp().GetTopWindow(); |
| 188 | } |
| 189 | |
| 190 | // Custom conversion for wxWindow. |
| 191 | struct convert_wxWindow |
| 192 | { |
| 193 | // Method that does the conversion. Note that it takes a reference to wxWindow, |
| 194 | // not a reference to a pointer. This is needed, because the return value policy |
| 195 | // converts the objects not the pointers. |
| 196 | static PyObject* convert(wxWindow const& o) |
| 197 | { |
| 198 | // Convert the pointer to wxWindow, instead of its value. This is how |
| 199 | // it should be done to convert wxObjects to wxPython. The object will be |
| 200 | // recognized well in python |
| 201 | PyObject* arg = wxPyMake_wxObject(const_cast<wxWindow*>(&o), false); |
| 202 | return arg; |
| 203 | } |
| 204 | }; |
| 205 | |
| 206 | // Wrapper code |
| 207 | using namespace boost::python; |
| 208 | BOOST_PYTHON_MODULE(MyApp) |
| 209 | { |
| 210 | def("getMainFrame", getMainFrame, return_value_policy<return_pointee_value>()); |
| 211 | |
| 212 | // register the custom converter |
| 213 | // converter for wxWindow, its conversion_struct, false tells boost that |
| 214 | // we do not have a get_pytype() method in it. |
| 215 | to_python_converter<wxWindow, convert_wxWindow, false>(); |
| 216 | } |
| 217 | </pre> |
| 218 | In Python: The example assumes that you call the python function <code>doit</code> from C++: |
| 219 | <pre> |
| 220 | def doit(): |
| 221 | w = MyApp.getMainFrame() |
| 222 | w.Hide() |
| 223 | print "Haha, it's gone!" |
| 224 | w.Show() |
| 225 | return 0 |
| 226 | |
| 227 | </pre> |
| 228 | <p>Note that the returned wxWindow is the same object as the return value of <code>getMainFrame</code> because of |
| 229 | the custom construction for <code>boost::python::object</code> from wxWindow. The conversion just converts the pointer, |
| 230 | not the object itself.</p> |
| 231 | |
| 232 | <p>Revised |
| 233 | <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan --> |
| 234 | 22 July, 2008 |
| 235 | <!--webbot bot="Timestamp" endspan i-checksum="39359" --> |
| 236 | </p> |
| 237 | |
| 238 | <p><i>© Copyright Maximilian Matthe, Roman Yakovenko 2006, 2008.</i></p> |
| 239 | </body> |
| 240 | </html> |
| 241 | |