]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [section boost/python/call_method.hpp] |
2 | [section Introduction] | |
3 | <boost/python/call_method.hpp> defines the call_method family of overloaded function templates, used to invoke callable attributes of Python objects from C++. | |
4 | [endsect] | |
5 | [section Function `call_method`] | |
6 | `` | |
7 | template <class R, class A1, class A2, ... class An> | |
8 | R call_method(PyObject* self, char const* method, A1 const&, A2 const&, ... An const&) | |
9 | `` | |
10 | [variablelist | |
11 | [[Requires][`R` is a pointer type, reference type, or a complete type with an accessible copy constructor]] | |
12 | [[Effects][Invokes `self.method(a1, a2, ...an)` in Python, where `a1...an` are the arguments to `call_method()`, converted to Python objects. For a complete semantic description, see this page.]] | |
13 | [[Returns][The result of the Python call, converted to the C++ type `R`.]] | |
14 | [[Rationale][`call_method` is critical to implementing C++ virtual functions which are overridable in Python, as shown by the example below.]] | |
15 | ] | |
16 | [endsect] | |
17 | [section Example] | |
18 | The following C++ illustrates the use of `call_method` in wrapping a class with a virtual function that can be overridden in Python: | |
19 | C++ Module Definition | |
20 | `` | |
21 | #include <boost/python/module.hpp> | |
22 | #include <boost/python/class.hpp> | |
23 | #include <boost/utility.hpp> | |
24 | #include <cstring> | |
25 | ||
26 | // class to be wrapped | |
27 | class Base | |
28 | { | |
29 | public: | |
30 | virtual char const* class_name() const { return "Base"; } | |
31 | virtual ~Base(); | |
32 | }; | |
33 | ||
34 | bool is_base(Base* b) | |
35 | { | |
36 | return !std::strcmp(b->class_name(), "Base"); | |
37 | } | |
38 | ||
39 | // Wrapper code begins here | |
40 | using namespace boost::python; | |
41 | ||
42 | // Callback class | |
43 | class Base_callback : public Base | |
44 | { | |
45 | public: | |
46 | Base_callback(PyObject* self) : m_self(self) {} | |
47 | ||
48 | char const* class_name() const { return call_method<char const*>(m_self, "class_name"); } | |
49 | char const* Base_name() const { return Base::class_name(); } | |
50 | private: | |
51 | PyObject* const m_self; | |
52 | }; | |
53 | ||
54 | using namespace boost::python; | |
55 | BOOST_PYTHON_MODULE(my_module) | |
56 | { | |
57 | def("is_base", is_base); | |
58 | ||
59 | class_<Base,Base_callback, noncopyable>("Base") | |
60 | .def("class_name", &Base_callback::Base_name) | |
61 | ; | |
62 | ||
63 | } | |
64 | `` | |
65 | Python code: | |
66 | `` | |
67 | >>> from my_module import * | |
68 | >>> class Derived(Base): | |
69 | ... def __init__(self): | |
70 | ... Base.__init__(self) | |
71 | ... def class_name(self): | |
72 | ... return self.__class__.__name__ | |
73 | ... | |
74 | >>> is_base(Base()) # calls the class_name() method from C++ | |
75 | 1 | |
76 | >>> is_base(Derived()) | |
77 | 0 | |
78 | `` | |
79 | [endsect] | |
80 | [endsect] |