Index: boost/python/return_pointee_value.hpp
===================================================================
--- boost/python/return_pointee_value.hpp (revision 0)
+++ boost/python/return_pointee_value.hpp (revision 0)
@@ -0,0 +1,69 @@
+// Copyright Roman Yakovenko, Maximilian Matthe 2006, 2008.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+/*
+ * Generic return value policy for functions returning pointers which should be
+ * exposed as values. Can be used to return pointers to non-exposed types.
+ *
+ * The code is adapted from
+ * http://mail.python.org/pipermail/c++-sig/2006-November/011568.html .
+ */
+#ifndef RETURN_POINTEE_VALUE_9_11_2006
+#define RETURN_POINTEE_VALUE_9_11_2006
+
+# include
+
+
This return value policy can only be used with types that were exposed with boost.python before.
reference_existing_object synopsis|
+ |
+
+
+ Boost.Python+ +Header + <boost/python/return_pointee_value.hpp>+ |
+
return_pointee_valuereturn_pointee_value synopsisreturn_pointee_value metafunctionsreturn_pointee_valuereturn_pointee_value is a model of ResultConverterGenerator
+ which can be used to wrap C++ functions, that return a pointer to a C++ object. The
+ policy implements the following logic:
+
+
+if return value is NULL pointer: + return None +else: + return bp::object( * return value ) ++ + It passes the value of the pointee to python, thus the conversion for T is used, if + return value is of type T*. +
This return_value_policy can therefore be used to return pointers to python, which + types are not known to boost.python but only a conversion for the pointees. Therefore this + policy should be used to return pointers to objects whose types were wrapped with + other tools, such as SWIG (see example).
+ +Please note: This policy does not take ownership of the wrapped pointer. If the + object pointed to is deleted in C++, the python-object will become invalid too, if your custom + conversion depends on the original object.
+ +return_pointee_value synopsis
+namespace boost { namespace python
+{
+ struct return_pointee_value
+ {
+ template <class T> struct apply;
+ };
+}}
+
+
+ return_pointee_value metafunctions+template <class T> struct apply ++ + + +
Example 1: This example demonstrates the trivial use of return_pointee_value for returning
+ the value that the returned pointer points to:
+
In C++:
+
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/return_pointee_value.hpp>
+#include <boost/python/return_value_policy.hpp>
+#inlcude <wxPython.h>
+#include <utility>
+
+// The function which is going to be wrapped:
+int* get_value()
+{
+ static int val = 42;
+ return &val;
+}
+
+// Function that returns a NULL-Pointer
+int* get_null_value()
+{
+ return NULL;
+}
+
+// The wrapper
+BOOST_PYTHON_MODULE(example)
+{
+ using namespace boost::python;
+ // Wrap the functions with return_pointee_value
+ def("get_value", get_value, return_value_policy<return_pointee_value>());
+ def("get_null_value", get_null_value, return_value_policy<return_pointee_value>());
+}
+
+ In Python:
++>>> import example +>>> f = example.get_value() +>>> print f +42 +>>> f = 5 +>>> print example.get_value() +42 +>>> assert None is example.get_null_value() ++
Note that the value of the static C++-variable val is not changed when python assigns
+ a new value to f. This is caused by the logic of return_pointee_value: It returns
+ the boost::python::object which is constructed from *val.
Example 2: The following example uses return_pointee_value to return an object that is wrapped + with SWIG. I use the wxPython-API because it's easier to understand.
+ +In C++:
+
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/return_pointee_value.hpp>
+#include <boost/python/return_value_policy.hpp>
+#inlcude <wxPython.h>
+#include <utility>
+
+// The following code assumes that there is set up a
+// working wxWidgets application
+
+// Function to wrap:
+wxWindow* getMainFrame()
+{
+ return wxGetApp().GetTopWindow();
+}
+
+// Custom conversion for wxWindow.
+struct convert_wxWindow
+{
+ // Method that does the conversion. Note that it takes a reference to wxWindow,
+ // not a reference to a pointer. This is needed, because the return value policy
+ // converts the objects not the pointers.
+ static PyObject* convert(wxWindow const& o)
+ {
+ // Convert the pointer to wxWindow, instead of its value. This is how
+ // it should be done to convert wxObjects to wxPython. The object will be
+ // recognized well in python
+ PyObject* arg = wxPyMake_wxObject(const_cast(&o), false);
+ return arg;
+ }
+};
+
+// Wrapper code
+using namespace boost::python;
+BOOST_PYTHON_MODULE(MyApp)
+{
+ def("getMainFrame", getMainFrame, return_value_policy());
+
+ // register the custom converter
+ // converter for wxWindow, its conversion_struct, false tells boost that
+ // we do not have a get_pytype() method in it.
+ to_python_converter<wxWindow, convert_wxWindow, false>();
+}
+
+ In Python: The example assumes that you call the python function doit from C++:
++def doit(): + w = MyApp.getMainFrame() + w.Hide() + print "Haha, it's gone!" + w.Show() + return 0 + ++
Note that the returned wxWindow is the same object as the return value of getMainFrame because of
+the custom construction for boost::python::object from wxWindow. The conversion just converts the pointer,
+not the object itself.
Revised + + 22 July, 2008 + +
+ +© Copyright Maximilian Matthe, Roman Yakovenko 2006, 2008.
+ + + Index: libs/python/test/return_pointee_value.cpp =================================================================== --- libs/python/test/return_pointee_value.cpp (revision 0) +++ libs/python/test/return_pointee_value.cpp (revision 0) @@ -0,0 +1,55 @@ +// Copyright Maximilian Matthe 2008. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include