Introduction
pybind11 enables calling C++ code from Python with minimal boilerplate. Inspired by Boost.Python but with a focus on compile-time efficiency and modern C++11/14/17 features, it keeps binding code concise while generating lean binaries.
What pybind11 Does
- Exposes C++ functions, classes, and templates as Python modules
- Automatically converts between Python and C++ types including STL containers
- Supports NumPy arrays with zero-copy buffer protocol access
- Enables Python-side inheritance from C++ virtual classes
- Provides CMake and setuptools build system integration
Architecture Overview
pybind11 is a header-only library that uses C++ template metaprogramming to generate CPython extension modules at compile time. It introspects function signatures to create type conversion code, embeds docstrings, and registers methods with the Python interpreter without runtime code generation.
Self-Hosting & Configuration
- Install via pip: pip install pybind11, or include as a Git submodule
- CMake: use pybind11_add_module() for seamless integration
- setuptools: use pybind11.setup_helpers for building wheels
- Requires a C++11 compatible compiler (GCC 4.8+, Clang 3.3+, MSVC 2015+)
- Header-only means no shared library dependency at runtime
Key Features
- Header-only with no external dependencies beyond Python and a C++ compiler
- Generates compact binaries significantly smaller than Boost.Python equivalents
- First-class NumPy support with direct buffer access
- Transparent exception translation between C++ and Python
- Supports Python's GIL release for concurrent native execution
Comparison with Similar Tools
- Boost.Python — mature but heavy; pybind11 achieves similar functionality with faster compile times and smaller binaries
- SWIG — generates bindings for many languages but requires interface files; pybind11 uses pure C++
- cython — compiles Python-like code to C; pybind11 wraps existing C++ directly
- nanobind — newer successor by the same author; smaller scope but faster compile for simple cases
- cffi — C-only foreign function interface; cannot wrap C++ classes or templates
FAQ
Q: Does pybind11 support Python 2? A: No. pybind11 v2.12+ requires Python 3.7 or newer. Legacy Python 2 support was dropped.
Q: Can I pass NumPy arrays to C++ without copying? A: Yes. pybind11 provides py::array_t which maps directly to NumPy buffers with zero-copy semantics.
Q: How does pybind11 handle the GIL? A: Use py::gil_scoped_release in long-running C++ code to release the GIL and allow other Python threads to proceed.
Q: Is pybind11 compatible with PyPy? A: Partial support exists through the CPython ABI compatibility layer, but CPython remains the primary target.