Calling C Language Programs from Python

In Windows, if your C language project includes include/ (header files) and src/ (source code) folders, you can use CPython extension to package it as an importable Python module. Here are the complete steps:

1. Project Structure

Assuming your C language project directory is as follows:

my_project/
│-- include/
│   ├── mylib.h
│-- src/
│   ├── mylib.c
│-- setup.py
│-- main.py  # Test Python code

2. Write C Code

<span>**include/mylib.h**</span>

#ifndef MYLIB_H
#define MYLIB_H

int add(int a, int b);
int multiply(int a, int b);

#endif

<span>**src/mylib.c**</span>

#include "mylib.h"

int add(int a, int b) {
    return a + b;
}

int multiply(int a, int b) {
    return a * b;
}

<span>**src/mymodule.c**</span> (Python binding code)

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "mylib.h"

// Binding add() function
static PyObject* py_add(PyObject* self, PyObject* args) {
    int a, b;
    if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
        return NULL;
    }
    return PyLong_FromLong(add(a, b));
}

// Binding multiply() function
static PyObject* py_multiply(PyObject* self, PyObject* args) {
    int a, b;
    if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
        return NULL;
    }
    return PyLong_FromLong(multiply(a, b));
}

// Define methods in the module
static PyMethodDef MyMethods[] = {
    {"add", py_add, METH_VARARGS, "Add two numbers"},
    {"multiply", py_multiply, METH_VARARGS, "Multiply two numbers"},
    {NULL, NULL, 0, NULL}
};

// Define the module
static struct PyModuleDef mymodule = {
    PyModuleDef_HEAD_INIT,
    "mymodule",
    NULL,
    -1,
    MyMethods
};

// Initialize the module
PyMODINIT_FUNC PyInit_mymodule(void) {
    return PyModule_Create(&mymodule);
}

**3. Write **<span>**setup.py**</span>

Create <span>setup.py</span> to package the C code:

from setuptools import setup, Extension

mymodule = Extension(
    "mymodule",
    sources=["src/mymodule.c", "src/mylib.c"],  # All C source files
    include_dirs=["include"],  # Header file directory
)

setup(
    name="mymodule",
    version="1.0",
    description="A simple C extension for Python",
    ext_modules=[mymodule],
)

4. Compile C Extension

Open Windows CMD or PowerShell, navigate to the <span>my_project/</span> directory, and run:

# Use this to install the toolchain
conda install m2w64-toolchain

set DISTUTILS_USE_SDK=1
set MSSdk=1
python setup.py build_ext --compiler=mingw32 --inplace

This will generate in the current directory:

  • <span>mymodule.cp38-win_amd64.pyd</span> (Windows version of the Python shared library)

5. Use in Python

Create <span>main.py</span>:

import mymodule

print(mymodule.add(3, 5))       # Output 8
print(mymodule.multiply(3, 5))  # Output 15

Run:

python main.py

**6. Package as an Installable **<span>**.whl**</span>

If you want to package it as a Python installable <span>.whl</span> file:

pip install wheel
python setup.py bdist_wheel

This will generate a <span>.whl</span> file in the <span>dist/</span> directory, which can be installed using <span>pip install mymodule.whl</span>.

Leave a Comment