Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
How to wrap C code in Python
#include <Python.h>
#include <numpy/arrayobject.h>
#include "chi2.h"
/* Docstrings */
static char module_docstring[] =
"This module provides an interface for calculating chi-squared using C.";
static char chi2_docstring[] =
"Calculate the chi-squared of some data given a model.";
/* Available functions */
static PyObject *chi2_chi2(PyObject *self, PyObject *args);
/* Module specification */
static PyMethodDef module_methods[] = {
{"chi2", chi2_chi2, METH_VARARGS, chi2_docstring},
/* Initialize the module */
PyMODINIT_FUNC init_chi2(void)
PyObject *m = Py_InitModule3("_chi2", module_methods, module_docstring);
if (m == NULL)
/* Load `numpy` functionality. */
static PyObject *chi2_chi2(PyObject *self, PyObject *args)
double m, b;
PyObject *x_obj, *y_obj, *yerr_obj;
/* Parse the input tuple */
if (!PyArg_ParseTuple(args, "ddOOO", &m, &b, &x_obj, &y_obj,
return NULL;
/* Interpret the input objects as numpy arrays. */
PyObject *x_array = PyArray_FROM_OTF(x_obj, NPY_DOUBLE, NPY_IN_ARRAY);
PyObject *y_array = PyArray_FROM_OTF(y_obj, NPY_DOUBLE, NPY_IN_ARRAY);
PyObject *yerr_array = PyArray_FROM_OTF(yerr_obj, NPY_DOUBLE,
/* If that didn't work, throw an exception. */
if (x_array == NULL || y_array == NULL || yerr_array == NULL) {
return NULL;
/* How many data points are there? */
int N = (int)PyArray_DIM(x_array, 0);
/* Get pointers to the data as C-types. */
double *x = (double*)PyArray_DATA(x_array);
double *y = (double*)PyArray_DATA(y_array);
double *yerr = (double*)PyArray_DATA(yerr_array);
/* Call the external C function to compute the chi-squared. */
double value = chi2(m, b, x, y, yerr, N);
/* Clean up. */
if (value < 0.0) {
"Chi-squared returned an impossible value.");
return NULL;
/* Build the output tuple */
PyObject *ret = Py_BuildValue("d", value);
return ret;
#include "chi2.h"
double chi2(double m, double b, double *x, double *y, double *yerr, int N) {
int n;
double result = 0.0, diff;
for (n = 0; n < N; n++) {
diff = (y[n] - (m * x[n] + b)) / yerr[n];
result += diff * diff;
return result;
double chi2(double m, double b, double *x, double *y, double *yerr, int N);
from distutils.core import setup, Extension
import numpy.distutils.misc_util
c_ext = Extension("_chi2", ["_chi2.c", "chi2.c"])

This comment has been minimized.

Copy link

@beaylott beaylott commented Aug 10, 2012

How about a ctypes version: ...


This comment has been minimized.

Copy link

@AraHaan AraHaan commented Dec 27, 2016

Nice code however what if my module does not need fucntions but need to do something like this where it calls classes from a backend module.

from importlib.machinery import FileFinder
from ._pycx_backend import *
import sys

extension_importers = [JsonImporter(), PycxImporter()]
hook_list = []
for importer in extension_importers:
    hook_list.append((importer.find_loader, importer.extensions))

sys.path_hooks.insert(0, FileFinder.path_hook(*hook_list))

Basically I want to write this in using C Code similar to how you wrote this without using all too annoying Cython because it is entirely unreadable.


This comment has been minimized.

Copy link

@RitamDey RitamDey commented Apr 11, 2017

Can't get it work on Python3.6. Importing in REPL tells me that Py_InitModule3

screenshot from 2017-04-11 21-11-32

Edit: Confirmed its initialization function outdated. Here is the updated gist from StackOverflow:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment