/* example/example-virtual-functions.cpp -- overriding virtual functions from Python Copyright (c) 2016 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #include "example.h" #include /* This is an example class that we'll want to be able to extend from Python */ class ExampleVirt { public: ExampleVirt(int state) : state(state) { cout << "Constructing ExampleVirt.." << endl; } ~ExampleVirt() { cout << "Destructing ExampleVirt.." << endl; } virtual int run(int value) { std::cout << "Original implementation of ExampleVirt::run(state=" << state << ", value=" << value << ")" << std::endl; return state + value; } virtual bool run_bool() = 0; virtual void pure_virtual() = 0; private: int state; }; /* This is a wrapper class that must be generated */ class PyExampleVirt : public ExampleVirt { public: using ExampleVirt::ExampleVirt; /* Inherit constructors */ virtual int run(int value) { /* Generate wrapping code that enables native function overloading */ PYBIND11_OVERLOAD( int, /* Return type */ ExampleVirt, /* Parent class */ run, /* Name of function */ value /* Argument(s) */ ); } virtual bool run_bool() { PYBIND11_OVERLOAD_PURE( bool, /* Return type */ ExampleVirt, /* Parent class */ run_bool, /* Name of function */ /* This function has no arguments. The trailing comma in the previous line is needed for some compilers */ ); } virtual void pure_virtual() { PYBIND11_OVERLOAD_PURE( void, /* Return type */ ExampleVirt, /* Parent class */ pure_virtual, /* Name of function */ /* This function has no arguments. The trailing comma in the previous line is needed for some compilers */ ); } }; int runExampleVirt(ExampleVirt *ex, int value) { return ex->run(value); } bool runExampleVirtBool(ExampleVirt* ex) { return ex->run_bool(); } void runExampleVirtVirtual(ExampleVirt *ex) { ex->pure_virtual(); } void init_ex_virtual_functions(py::module &m) { /* Important: indicate the trampoline class PyExampleVirt using the third argument to py::class_. The second argument with the unique pointer is simply the default holder type used by pybind11. */ py::class_, PyExampleVirt>(m, "ExampleVirt") .def(py::init()) /* Reference original class in function definitions */ .def("run", &ExampleVirt::run) .def("run_bool", &ExampleVirt::run_bool) .def("pure_virtual", &ExampleVirt::pure_virtual); m.def("runExampleVirt", &runExampleVirt); m.def("runExampleVirtBool", &runExampleVirtBool); m.def("runExampleVirtVirtual", &runExampleVirtVirtual); }