🔌 Python C Extensions
Writing C extensions allows you to extend Python with compiled C code. This is useful for performance-critical sections or for interfacing with existing C libraries.
🧠 The Python/C API
Python provides a C API (Python.h) to interact with the Python interpreter.
🛠 Anatomy of a C Extension
A basic C extension involves:
1. Including Python.h.
2. Writing the C function.
3. Defining the method table.
4. Defining the module definition structure.
5. Initializing the module.
example.c
#include <Python.h>
// 1. The C function
static PyObject* method_fputs(PyObject* self, PyObject* args) {
char* str;
char* filename = NULL;
int bytes_copied = -1;
// Parse arguments
if (!PyArg_ParseTuple(args, "ss", &str, &filename)) {
return NULL;
}
FILE* fp = fopen(filename, "w");
bytes_copied = fputs(str, fp);
fclose(fp);
return PyLong_FromLong(bytes_copied);
}
// 2. Method Table
static PyMethodDef FputsMethods[] = {
{"fputs", method_fputs, METH_VARARGS, "Python interface for fputs C library function"},
{NULL, NULL, 0, NULL}
};
// 3. Module Definition
static struct PyModuleDef fputsmodule = {
PyModuleDef_HEAD_INIT,
"fputs",
"Python interface for the fputs C library function",
-1,
FputsMethods
};
// 4. Module Initialization
PyMODINIT_FUNC PyInit_fputs(void) {
return PyModule_Create(&fputsmodule);
}
🏗 Building the Extension
Use setuptools to build.
setup.py
from setuptools import setup, Extension
module = Extension('fputs', sources=['example.c'])
setup(
name='Fputs',
version='1.0',
description='Python interface for fputs C library function',
ext_modules=[module]
)
Build: python setup.py build_ext --inplace
🧩 Reference Counting
One of the most critical aspects of C extensions is managing reference counts.
Py_INCREF(obj): Increment reference count.Py_DECREF(obj): Decrement reference count.
If you mess this up, you get memory leaks or segmentation faults.
📝 Summary
- ✅ Low Level: Gives you full control but requires manual memory management.
- ✅ Performance: Maximum performance possible.
- ✅ Complexity: Harder to write and maintain than Cython.
- ✅ GIL: You must be aware of the GIL and release it for long-running C operations if you want parallelism.
Created with ❤️ by Pynfinity