pybind11
pybind11 is a lightweight, header-only library that provides seamless operability between C++11 (and newer) and Python. It's primarily used to create Python bindings for existing C++ code, minimizing boilerplate through compile-time introspection. The library is actively maintained (current version 3.0.3) with frequent bug fixes and regular major releases that often introduce ABI bumps. It supports CPython 3.8+, PyPy3 7.3.17+, and GraalPy 24.1+.
Warnings
- breaking pybind11 v3.0.0 introduced an ABI bump. Extensions built with v3.0.0 or later are not ABI-compatible with those built using v2.x versions (e.g., v2.13).
- breaking Support for older Python and CMake versions was removed in v3.0.0. Specifically, Python 3.7, PyPy 3.8/3.9, and CMake < 3.15 are no longer supported.
- breaking In v3.0.0, CMake support defaults to the modern `FindPython` module. Projects using older `PYTHON_*` variables may find them ignored or deprecated.
- deprecated The `py::enum_` API for exposing C++ enumerations is deprecated in favor of `py::native_enum`.
- gotcha Improper Global Interpreter Lock (GIL) management is a common source of bugs. Avoid invoking Python functions in global static contexts or having global pybind11 objects.
- gotcha When working with sub-interpreters (enabled by default in v3.0.0), avoid sharing Python objects across different sub-interpreters and minimize global/static C++ state in your modules.
- gotcha When casting from a raw `PyObject*` to a `py::object` subclass (e.g., `py::str`), omitting the template argument to `py::cast` will silently result in incorrect behavior.
Install
-
pip install pybind11
Imports
- Generated Python Module
import your_cpp_module
Quickstart
/* example.cpp */
#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"; // optional module docstring
m.def("add", &add, "A function which adds two numbers");
}
# Python (in the same directory or after installation)
import example
result = example.add(1, 2)
print(f"The result is: {result}") # Expected: The result is: 3
# To build from source (Unix-like systems):
# Ensure C++ compiler (e.g., g++), Python dev headers, and pybind11 are available.
# c++ -O3 -Wall -shared -std=c++11 -fPIC \
# $(python3 -m pybind11 --includes) example.cpp \
# -o example$(python3 -m pybind11 --extension-suffix)