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 ↔ Python str
  • int, double, bool ↔ Python equivalents
  • std::vector<T> can be exposed with vector_indexing_suite
  • std::map<K,V> can be exposed with map_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

AspectBoost.Pythonpybind11
OriginEarly 2000s (Boost)2015 (inspired by Boost.Python)
DependenciesEntire Boost libraryHeader-only, no dependencies
Compile timeSlow (heavy Boost headers)Faster (lighter templates)
C++ standardC++03 compatibleRequires C++11 or later
CommunityMature but less activeVery active development
API similarityNearly 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.

pythonboostcpptemplate-metaprogrammingbindings

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.