Author image

Pybind 11 Tutorial


Difficulty:
1/5


Pybind11 is a lightweight header only library that exposes c++ types in Python. 8k lines entire library. 5k LOC core codebase. You can use it to extend python with C/C++ written python extensions - similar to CPython but in a much easier and up-to-date method. Or you can embed the python interpreter in C++ allowing for python scripting in a C++ application. It goes both ways it's not particularly hard and you basically get to marry the Beauty and the Beast together (and C++ is not the beauty..).

Tip:

If you don't have a python distribution installed on your system you can extract the python36.zip and python36.dll from the pybinding\x64\Debug\python-3.6.6-embed-amd64.zip file and place them on the same directory as the output executable. They will work exactly the same.


pybind_module is a static library project configured with .pyd target extension. pybinding is an application project.

C++ Application project setup:

  1. create new C++ project
  2. use the same platform architecture as that of your Python interpreter. eg if you have Python 64bit installed use x64
  3. download pybind11 from the github repository (linked down below)
  4. add in your project's includes the pybind include directory as well as your own Python distribution's include directory (eg C:\Program Files\Python36\include)
  5. for libraries add the directory to your Python distribution's libs folder (not the lib folder)
  6. include the python3x.lib in Release configuration and python3x_d.lib in Debug configuration
  7. #include "path/to/pybind11/embed.h" (first) and #include "Python.h" (second) minimally in your main file

Yes I know the initial configuration can be a bit of a pain. But that was it! Check pybinding/main.cpp for how simple it is.

This line: py::scoped_interpreter guard{}; binds the Python interpreter.

The line: PYBIND11_EMBEDDED_MODULE( embedded_module, m ) acts as the glue code between C++ and Python. Use it to expose C++ utilities (functions, classes etc.) to the Python module. Then you can simply import the python module in python interpreter and make use of these C++ utilities right from inside the Python interpreter.

C++ Module project setup:

  1. Build the pybind module project to create your very first custom python module from c++. It contains a single function called greet() 
  2. go to the output directory x64/Debug/ where you'll find “pybind\module.pyd”
  3. run the python interpreter and type:import pybind_module!

Example:

>>  python
>>> import pybind_module as pm
>>> pm.greet()
Hello World

Mixed language debugging

To take things to the next level and enable Mixed language debugging Python and C++ together we'll have to launch Visual Studio Installer (Tools -> Get Tools and Features) and tick Python Development -> “Python Native Development Tools”. It's approximately a 3GB installation.

Then in your solution select the arrow next to debugging (the one with the play button) and select “Python/Native Debugging”. Now you can add python file to your C++ solution make calls to them from the c++ code (like I do in my project) and place breakpoints either in C++ or Python code. It's really easy and intuitive.

I also plan to use pybind11 as a scripting language for a video game engine project. I never wanted to resort to Lua as I don't want to dedicate more time to learn another language (even though Lua is easy-peasy); I still prefer to use the singularly beautiful and easy Python, even if it is presumably slower than Lua.


I used Windows 8.1 x86_64, Visual Studio 2017, C++17 and Python v3.6.6 (Debugging symbols included) to build the project.

Github

Github repository link.

Acknowledgements

Create a C++ extension for Python Microsoft article.
pybind11 github.


0 likes