Python Boost.Python Bindings — Core Concepts
Boost.Python is a C++ library from the Boost collection that enables seamless interoperability between C++ and Python. Unlike code generators such as SWIG, Boost.Python uses C++ template metaprogramming to declare bindings directly in C++ source files.
How Binding Declaration Works
You write binding declarations in a BOOST_PYTHON_MODULE block:
#include <boost/python.hpp>
using namespace boost::python;
class Greeter {
public:
Greeter(const std::string& name) : name_(name) {}
std::string greet() const { return "Hello, " + name_ + "!"; }
private:
std::string name_;
};
BOOST_PYTHON_MODULE(mymodule) {
class_<Greeter>("Greeter", init<std::string>())
.def("greet", &Greeter::greet);
}
Python usage:
from mymodule import Greeter
g = Greeter("World")
print(g.greet()) # "Hello, World!"
No separate interface file, no code generation step. The C++ compiler resolves all the template machinery at compile time.
Key Features
Automatic Type Conversion
Boost.Python converts standard types automatically:
std::string↔ Pythonstrint,double,bool↔ Python equivalentsstd::vector<T>can be exposed withvector_indexing_suitestd::map<K,V>can be exposed withmap_indexing_suite
Inheritance and Polymorphism
C++ class hierarchies are preserved in Python:
class Shape {
public:
virtual double area() const = 0;
virtual ~Shape() {}
};
class Circle : public Shape {
public:
Circle(double r) : radius(r) {}
double area() const override { return 3.14159 * radius * radius; }
double radius;
};
BOOST_PYTHON_MODULE(shapes) {
class_<Shape, boost::noncopyable>("Shape", no_init)
.def("area", pure_virtual(&Shape::area));
class_<Circle, bases<Shape>>("Circle", init<double>())
.def("area", &Circle::area)
.def_readwrite("radius", &Circle::radius);
}
Python’s isinstance(circle, Shape) returns True, and virtual dispatch works across the language boundary.
Function Overloading
Boost.Python handles C++ function overloading through explicit signatures:
class Calculator {
public:
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
};
BOOST_PYTHON_MODULE(calc) {
class_<Calculator>("Calculator")
.def("add", static_cast<int(Calculator::*)(int,int)>(&Calculator::add))
.def("add", static_cast<double(Calculator::*)(double,double)>(&Calculator::add));
}
Properties
Expose C++ getters and setters as Python properties:
class_<Config>("Config")
.add_property("width", &Config::get_width, &Config::set_width)
.add_property("name", &Config::get_name); // read-only
Boost.Python vs. Modern Alternatives
| Aspect | Boost.Python | pybind11 |
|---|---|---|
| Origin | Early 2000s (Boost) | 2015 (inspired by Boost.Python) |
| Dependencies | Entire Boost library | Header-only, no dependencies |
| Compile time | Slow (heavy Boost headers) | Faster (lighter templates) |
| C++ standard | C++03 compatible | Requires C++11 or later |
| Community | Mature but less active | Very active development |
| API similarity | — | Nearly identical syntax |
Pybind11 was explicitly designed as a lightweight successor to Boost.Python, with a nearly identical API but without the Boost dependency.
When to Use Boost.Python
- Your project already depends on Boost
- You’re maintaining an existing codebase that uses Boost.Python
- You need compatibility with older C++ compilers (pre-C++11)
- You’re working in an organization where Boost is the standard toolkit
Common Misconception
“Boost.Python requires you to install all of Boost.” While Boost.Python is part of the Boost collection, most package managers let you install just the boost-python component. On Ubuntu: apt install libboost-python-dev. On macOS: brew install boost-python3.
One Thing to Remember
Boost.Python pioneered the idea of declaring Python bindings directly in C++ using template metaprogramming. While pybind11 has largely succeeded it for new projects, Boost.Python remains a reliable and feature-complete choice — especially for codebases already embedded in the Boost ecosystem.
See Also
- Python Buffer Protocol The buffer protocol lets Python objects share raw memory without copying, like passing a notebook around the table instead of photocopying every page.
- Python Capsule Api Python Capsules let C extensions secretly pass pointers to each other through Python, like friends passing a sealed envelope through a mailbox.
- Python Cffi Bindings CFFI lets Python talk to fast C libraries, like giving your app a translator that speaks both languages at the same table.
- Python Extension Modules Api The C Extension API is how Python lets you plug in hand-built C code, like adding a turbo engine under your Python program's hood.
- Python Maturin Build Tool Maturin packages Rust code into Python libraries you can pip install, like a gift-wrapping service for super-fast code.