Intermediate Python

Python C Extensions

Few use-case where writing C extension for Python might make sense include:

  1. Integrating with existing C library
  2. Performance Optmizations

Creating C Extensions

#include <Python.h>

static PyObject*
say_hello(PyObject* self, PyObject* args)
{
    const char* name;

    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

    printf("Hello %s!\n", name);

    Py_RETURN_NONE;
}

static PyMethodDef HelloMethods[] =
{
    {"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inithello(void)
{
    (void) Py_InitModule("hello", HelloMethods);
}

As mentioned in TutorialsPoint Guide, there are four things we require

  1. Include Python.h, this gives access to Python’s internal APIs
  2. C function you want to expose as interface from module {In our example about it is static PyObject *say_hello(PyObject* self, PyObject* args)}
  3. Mapping of Python function names to C function names {In our case HelloMethods}
  4. An initialization function {In our case it is inithello}

Creating setup.py file

setup.py file will be responsible for building the module.

from distutils.core import setup, Extension

module1 = Extension('hello', sources = ['hellomodule.c'])

setup (name = 'PackageName',
        version = '1.0',
        description = 'This is a demo package',
        ext_modules = [module1])

Following is how to build and use the module, on shell

python setup.py install

On terminal

>>> from hello import say_hello
>>> say_hello("sidharth")

Note: If you’re interested in extending Python using C++, pybind11 seems to be a good option