<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <meta name="generator" content="HTML Tidy, see www.w3.org"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link rel="stylesheet" type="text/css" href="../boost.css"> <title>Boost.Python - <wrapper.hpp></title> <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 valign="top"> <h1 align="center"><a href="../index.html">Boost.Python</a></h1> <h2 align="center">Header <wrapper.hpp></h2> </table> <hr> <h2>Contents</h2> <dl class="page-index"> <dt><a href="#introduction">Introduction</a></dt> <dt><a href="#classes">Classes</a></dt> <dd> <dl class="page-index"> <dt><a href="#override-spec">Class template <code>override</code></a></dt> <dd> <dl class="page-index"> <dt><a href="#override-spec-synopsis">Class <code>override</code> synopsis</a></dt> <dt><a href="#override-spec-observers">Class <code>override</code> observer functions</a></dt> </dl> </dd> <dt><a href="#wrapper-spec">Class template <code>wrapper</code></a></dt> <dd> <dl class="page-index"> <dt><a href="#wrapper-spec-synopsis">Class <code>wrapper</code> synopsis</a></dt> <dt><a href="#wrapper-spec-observers">Class <code>wrapper</code> observer functions</a></dt> </dl> </dd> </dl> </dd> <dt><a href="#examples">Example(s)</a></dt> </dl> <hr> <h2><a name="introduction"></a>Introduction</h2> <p>To wrap a class <code>T</code> such that its virtual functions can be "overridden in Python"—so that the corresponding method of a Python derived class will be called when the virtual function is invoked from C++—you must create a C++ wrapper class derived from ``T`` that overrides those virtual functions so that they call into Python. This header contains classes that can be used to make that job easier.</p> <h2><a name="classes"></a>Classes</h2> <h3><a name="override-spec"></a>Class <code>override</code></h3> <p>Encapsulates a Python override of a C++ virtual function. An <code>override</code> object either holds a callable Python object or <code>None</code>.</p> <h4><a name="override-spec-synopsis"></a>Class <code>override</code> synopsis</h4> <pre> namespace boost { class override : object { public: <i>unspecified</i> operator() const; template <class A0> <i>unspecified</i> operator(A0) const; template <class A0, class A1> <i>unspecified</i> operator(A0, A1) const; ... template <class A0, class A1, ...class A<i>n</i>> <i>unspecified</i> operator(A0, A1, ...A<i>n</i>) const; }; }; </pre> <h4><a name="override-spec-observers"></a>Class <code>override</code> observer functions</h4> <pre> <i>unspecified</i> operator() const; template <class A0> <i>unspecified</i> operator(A0) const; template <class A0, class A1> <i>unspecified</i> operator(A0, A1) const; ... template <class A0, class A1, ...class A<i>n</i>> <i>unspecified</i> operator(A0, A1, ...A<i>n</i>) const; </pre> <dl class="function-semantics"> <dt><b>Effects:</b> If <code>*this</code> holds a callable Python object, it is invoked with the specified arguments in the manner specified <a href="callbacks.html">here</a>. Otherwise, throws <code><a href="errors.html#error_already_set-spec">error_already_set</a></code> .</dt> <dt><b>Returns:</b> An object of unspecified type that holds the Python result of the invocation and, when converted to a C++ type <code>R</code>, attempts to convert that result object to <code>R</code>. If that conversion fails, throws <code><a href= "errors.html#error_already_set-spec">error_already_set</a></code> .</dt> </dl> <h3><a name="wrapper-spec"></a>Class template <code>wrapper</code></h3> <p>Deriving your wrapper class from both ``T`` <i>and</i> ``wrapper<T> makes writing that derived class easier.</p> <h4><a name="wrapper-spec-synopsis"></a>Class template <code>wrapper</code> synopsis</h4> <pre> namespace boost { class wrapper { protected: override get_override(char const* name) const; }; }; </pre> <h4><a name="wrapper-spec-observers"></a>Class <code>wrapper</code> observer functions</h4> <pre> override get_override(char const* name) const; </pre> <dl class="function-semantics"> <dt><b>Requires:</b> <code>name</code> is a <a href= "definitions.html#ntbs">ntbs</a>.</dt> <dt><b>Returns:</b> If <code>*this</code> is the C++ base class subobject of a Python derived class instance that overrides the named function, returns an <code>override</code> object that delegates to the Python override. Otherwise, returns an <code>override</code> object that holds <code>None</code>.</dt> </dl> <h2><a name="examples"></a>Example</h2> <pre> #include <boost/python/module.hpp> #include <boost/python/class.hpp> #include <boost/python/wrapper.hpp> #include <boost/python/call.hpp> using namespace boost::python; // Class with one pure virtual function struct P { virtual ~P(){} virtual char const* f() = 0; char const* g() { return "P::g()"; } }; struct PCallback : P, wrapper<P> { char const* f() { #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // Workaround for vc6/vc7 return call<char const*>(this->get_override("f").ptr()); #else return this->get_override("f")(); #endif } }; // Class with one non-pure virtual function struct A { virtual ~A(){} virtual char const* f() { return "A::f()"; } }; struct ACallback : A, wrapper<A> { char const* f() { if (override f = this->get_override("f")) #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // Workaround for vc6/vc7 return call<char const*>(f.ptr()); #else return f(); #endif return A::f(); } char const* default_f() { return this->A::f(); } }; BOOST_PYTHON_MODULE_INIT(polymorphism) { class_<PCallback,boost::noncopyable>("P") .def("f", pure_virtual(&P::f)) ; class_<ACallback,boost::noncopyable>("A") .def("f", &A::f, &ACallback::default_f) ; } </pre> <p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan --> 31 October, 2004 <!--webbot bot="Timestamp" endspan i-checksum="39359" --> <p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2004</i> 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)</p>