pybind11: Creating Python Bindings for C++ Code
pybind11 is a lightweight, header-only library for C++ that lets you create high-performance bindings between C++ and Python. It's a modern, more convenient alternative to the Boost.Python library. The core idea is simple: you write a thin layer of "glue" code in C++ using pybind11 macros and templates, compile it into a dynamic library (a .so or .pyd file), and then import that file into Python as a regular module.
Why would you need this? In real-world projects, you often need to combine C++'s high performance and low-level control with Python's flexibility and rich ecosystem. You can write speed-critical code (numerical algorithms, image processing, hardware interaction) in C++ and then use it from Python, keeping the convenience of prototyping and data analysis. pybind11 makes this process as simple and intuitive as possible, automatically handling type conversions, memory management, and exception handling.
Key advantages of pybind11: minimal overhead when calling functions, full support for modern C++ (C++11 and later), automatic conversion of standard containers (std::vector, std::map) to Python lists and dictionaries, and a simple, expressive system for registering classes, methods, and properties. The library is actively developed and used in major projects like PyTorch, TensorFlow, and Open3D.
Installation
pybind11 is a header-only library, so installing it is as simple as copying the header files into your project. The easiest and recommended way is to use the pip package manager, which installs the library on your system and provides the pybind11-config utility to get compiler paths:
pip install pybind11
After installation, you can verify everything works by running:
pybind11-config --includes
This will output the compiler flags needed to include the pybind11 headers. To compile your module, you'll also need a C++ compiler (g++, clang, MSVC) and Python headers (usually installed with Python). Here's an example of compiling with CMake or directly via g++:
c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
Quick Start: Minimal Working Example
Create a file called example.cpp with the following content:
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int i, int j) {
return i + j;
}
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin";
m.def("add", &add, "A function that adds two numbers");
}
Compile it (replace python3 with your interpreter):
c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
Now you can use the module from Python:
import example
result = example.add(3, 4)
print(result) # Output: 7
print(example.__doc__) # Output: pybind11 example plugin
Key pybind11 Methods and Classes
Below are the library's key functions and classes used to create bindings.
1. PYBIND11_MODULE(name, variable)
Signature: PYBIND11_MODULE(name, variable) (macro)
What it does: Defines the entry point for a Python module. It creates an initialization function that is automatically called when Python imports the module. The name parameter must match the compiled module's filename (without extension), and variable is an instance of py::module_ that you use to register functions and classes.
Also in library
Authorization and Authentication in C# (.NET) — Complete Guide
PDF Generation in Swift (iOS/macOS): UIGraphicsPDFRenderer, PDFKit and Core Graphics
Dependency Injection Containers for Java: A Complete Overview