Pybind 11 Tutorial
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. Alternatively you can embed the python interpreter in C++ allowing for python scripting in a C++ application. It can work 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:
- create new C++ project
- use the same platform architecture as that of your Python interpreter eg. if you have Python 64bit installed use x64
- download pybind11 from the github repository (linked down below)
- add in your project's includes the pybind
include
directory as well as your own Python distribution'sinclude
directory (egC:\Program Files\Python36\include
) - for libraries add the directory to your Python distribution's
libs
folder (not the lib folder) - include the python3x.lib in Release configuration and python3x_d.lib in Debug configuration
#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 pyInterpreter{};
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:
- Build the pybind module project to create your very first custom python module from c++. It contains a single function called
greet()
- go to the output directory
x64/Debug/
where you'll find “pybind\module.pyd” - 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 get accustomed with another programming language (even one as simple and intuitive as Lua); I still prefer to use the singularly beautiful and easy Python, even if it is presumably slower than Lua.
I used Windows, Visual Studio, C++17 and Python v3.6.6 (+ Debugging symbols) to build the project.
Github
Github repository link.
Acknowledgements
Create a C++ extension for Python Microsoft article.
pybind11 github.