Skip to content

Instantly share code, notes, and snippets.

@dov
Last active October 8, 2019 09:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dov/c88dc60a6deaa461d09b1725420e8de0 to your computer and use it in GitHub Desktop.
Save dov/c88dc60a6deaa461d09b1725420e8de0 to your computer and use it in GitHub Desktop.
pybind11 shadow classes for C++ objects

Intro

Have you ever wondered how to create XJet like python bindings to your own C++ classes, with a modern python binding package? Wonder no longer!

// Example to allocate a class in C++, wrap it as a python class and call a
// member of it from python.
//
// 2019-10-08 Tue

#include <stdio.h>
#include <pybind11/pybind11.h>
#include <pybind11/embed.h>

using namespace std;
namespace py = pybind11;

class Cat
{
    public:
        Cat() {}
        int m_counter = 0;

    void meow() { printf("meeeoww %d!\n", ++m_counter); }
};

class Application
{
    public:
    Application()
    {
        // Create application modules
        m_cat = make_shared<Cat>();

        // Construct python wrappers for them
        py::module m("MyApp");
        py::class_<Cat, shared_ptr<Cat>>(m, "CCat")
            .def("meow", &Cat::meow);

        // Assign them to the "application" dictionary
        m.add_object("Cat", py::cast(m_cat));

        // Assign the module to the global dictionary
        py::globals()["MyApp"] = m;
    }

    shared_ptr<Cat> get_cat() { return m_cat; }

    void run_python(const string& pycode)
    {
        py::exec(pycode);
    }
  
    private:
    shared_ptr<Cat> m_cat;
};
  
int main(int argc, char *argv[])
{
    py::scoped_interpreter guard{};
  
    Application app;

    app.get_cat()->meow();
    app.run_python("MyApp.Cat.meow()\n"
                   );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment