Python SWIG Interface Generator — Core Concepts

SWIG (Simplified Wrapper and Interface Generator) is a tool that reads C and C++ declarations and automatically generates the glue code needed to call those functions from Python and other scripting languages. It has been in active development since 1995 and remains widely used for wrapping legacy codebases.

What SWIG Does

Instead of manually writing CPython extension code (which involves reference counting, argument parsing, and type conversion), you write an interface file that tells SWIG which C/C++ declarations to expose. SWIG generates the complete wrapper.

The Interface File

A .i file is SWIG’s configuration. A minimal example:

/* mylib.i */
%module mylib

%{
#include "mylib.h"
%}

/* Tell SWIG to wrap everything in this header */
%include "mylib.h"

The %{ ... %} block is copied verbatim into the generated C file (for #include directives). The %include directive tells SWIG to parse the header and generate wrappers for all public declarations.

How SWIG Processes Code

  1. Parsing: SWIG has its own C/C++ parser that reads header files and understands functions, classes, enums, typedefs, and templates.
  2. Type mapping: SWIG converts C types to Python objects using a typemap system. int becomes a Python int, char* becomes str, and so on.
  3. Code generation: For each function and class, SWIG writes a C wrapper function that CPython’s extension API expects.
  4. Module registration: SWIG generates the PyInit_mylib function that Python calls at import time.

Key Features

Class Wrapping

SWIG maps C++ classes to Python classes automatically:

// In point.h
class Point {
public:
    double x, y;
    Point(double x, double y);
    double distance(const Point& other) const;
};

After SWIG processing, Python code works naturally:

from mylib import Point
p1 = Point(0, 0)
p2 = Point(3, 4)
print(p1.distance(p2))  # 5.0

Multi-Language Support

The same interface file can generate bindings for Python, Java, C#, Ruby, Go, Lua, and over 20 other languages. This is SWIG’s signature advantage — if your C library needs to be accessible from multiple languages, you write one .i file instead of separate bindings for each.

Typemaps

Typemaps customize how specific C types convert to and from Python:

%typemap(in) int flags {
    $1 = (int)PyLong_AsLong($input);
    if ($1 < 0) {
        PyErr_SetString(PyExc_ValueError, "flags must be non-negative");
        SWIG_fail;
    }
}

SWIG ships with built-in typemaps for standard types, STL containers (std::vector, std::string, std::map), and smart pointers.

Build Process

# Generate the wrapper
swig -python -c++ mylib.i

# This produces:
# - mylib_wrap.cxx (C++ glue code)
# - mylib.py (Python shadow module)

# Compile the wrapper into a shared library
g++ -shared -fPIC -I/usr/include/python3.12 \
    mylib_wrap.cxx mylib.cpp -o _mylib.so

The generated mylib.py provides Pythonic names and docstrings; _mylib.so contains the actual native code.

SWIG vs. Other Binding Tools

FeatureSWIGPyO3pybind11ctypes
LanguageC/C++RustC++C
Code generationAutomaticMacro-basedTemplate-basedNone (runtime)
Multi-language20+ languagesPython onlyPython onlyPython only
Template supportLimitedN/AFullN/A
Active ecosystemMature, stableGrowing fastVery activeBuilt-in

Common Misconception

“SWIG is outdated and you should always use pybind11.” SWIG and pybind11 solve different problems. SWIG excels when you have a large existing C/C++ codebase and need bindings for multiple languages quickly. Pybind11 excels when you’re writing new C++ specifically for Python. Many production systems use SWIG today, including parts of TensorFlow’s original Python bindings.

One Thing to Remember

SWIG is an automatic binding generator: point it at C/C++ headers, and it produces working Python extensions. Its unique strength is multi-language support — one interface file can target Python, Java, and a dozen other languages simultaneously.

pythonswigc-cppcode-generationinterop

See Also

  • Python Boost Python Bindings Boost.Python lets C++ code talk to Python using clever C++ tricks, like teaching two people to understand each other through a shared phrasebook.
  • 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.