Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Python 3 extension example
#include <stdio.h>
#include <Python.h>
// Module method definitions
static PyObject* hello_world(PyObject *self, PyObject *args) {
printf("Hello, world!\n");
Py_RETURN_NONE;
}
static PyObject* hello(PyObject *self, PyObject *args) {
const char* name;
if (!PyArg_ParseTuple(args, "s", &name)) {
return NULL;
}
printf("Hello, %s!\n", name);
Py_RETURN_NONE;
}
// Method definition object for this extension, these argumens mean:
// ml_name: The name of the method
// ml_meth: Function pointer to the method implementation
// ml_flags: Flags indicating special features of this method, such as
// accepting arguments, accepting keyword arguments, being a
// class method, or being a static method of a class.
// ml_doc: Contents of this method's docstring
static PyMethodDef hello_methods[] = {
{
"hello_world", hello_world, METH_NOARGS,
"Print 'hello world' from a method defined in a C extension."
},
{
"hello", hello, METH_VARARGS,
"Print 'hello xxx' from a method defined in a C extension."
},
{NULL, NULL, 0, NULL}
};
// Module definition
// The arguments of this structure tell Python what to call your extension,
// what it's methods are and where to look for it's method definitions
static struct PyModuleDef hello_definition = {
PyModuleDef_HEAD_INIT,
"hello",
"A Python module that prints 'hello world' from C code.",
-1,
hello_methods
};
// Module initialization
// Python calls this function when importing your extension. It is important
// that this function is named PyInit_[[your_module_name]] exactly, and matches
// the name keyword argument in setup.py's setup() call.
PyMODINIT_FUNC PyInit_hello(void) {
Py_Initialize();
return PyModule_Create(&hello_definition);
}
#!/usr/bin/env python3
# encoding: utf-8
from distutils.core import setup, Extension
hello_module = Extension('hello', sources = ['hello.c'])
setup(name='hello',
version='0.1.0',
description='Hello world module written in C',
ext_modules=[hello_module])
@yingdi11

This comment has been minimized.

Copy link

yingdi11 commented Aug 13, 2017

It is working ! very nice.Thank you

@ghost

This comment has been minimized.

Copy link

ghost commented Aug 17, 2017

A great little example. Thanks.

@s2339956

This comment has been minimized.

Copy link

s2339956 commented Aug 24, 2017

Thank you

@tryabin

This comment has been minimized.

Copy link

tryabin commented Oct 20, 2017

Thanks, went through several examples and this one was the first that worked for me.

@hannah-leitheiser

This comment has been minimized.

Copy link

hannah-leitheiser commented Feb 12, 2018

Thank you!

@SidChenTW

This comment has been minimized.

Copy link

SidChenTW commented Apr 17, 2018

The sample code also works in Windows environment.
Thank you.

@purple4reina

This comment has been minimized.

Copy link

purple4reina commented May 18, 2018

Can also do a pip install -e .

Thanks a ton!

@Arumugamvasu

This comment has been minimized.

Copy link

Arumugamvasu commented Dec 25, 2018

It's working good.

Hi ...i am not very familiar with c extension for python.I have some array calculation coding with c extension.but That's not working fine .am got some error when compile that code .anyone can help me...

I am currently trying to implement array multiplication with some formula in c .but don't really know how I would create empty array with input dimension and how to return from c function to extension main function.

My c code return array to main function.
#include "chie.h"

double chie(double m, double b, double *x, double *y, double *yerr, int N,double *result) {
int n;
double diff;
//double result = 0.0;
//static double result[5];
for (n = 0; n < N; n++) {
diff = (y[n] - (m * x[n] + b)) / yerr[n];
result[n]= diff * diff;
}

//return result;

}

then how to i catch the c array returned data to empty array.
this is my c extension main code.

#include <Python.h>
#include <numpy/arrayobject.h>
#include "chie.h"

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

static char module_docstring[] =
"This module provides an interface for calculating chi-squared using C.";
static char chie_docstring[] =
"Calculate the chi-squared of some data given a model.";

static PyObject *chi2_chi2(PyObject *self, PyObject *args);

static PyObject *chi2_chi2(PyObject *self, PyObject *args)
{
double m, b;
PyObject *x_obj, *y_obj, *yerr_obj;
double *result[5];

/* Parse the input tuple */
if (!PyArg_ParseTuple(args, "ddOOO", &m, &b, &x_obj, &y_obj,
                                    &yerr_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,
                                        NPY_IN_ARRAY);

/* If that didn't work, throw an exception. */
if (x_array == NULL || y_array == NULL || yerr_array == NULL) {
    Py_XDECREF(x_array);
    Py_XDECREF(y_array);
    Py_XDECREF(yerr_array);
    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. */
chie(m, b, x, y, yerr, N,result);

/* Clean up. */
Py_DECREF(x_array);
Py_DECREF(y_array);
Py_DECREF(yerr_array);

/*if (value < 0.0) {
    PyErr_SetString(PyExc_RuntimeError,
                "Chi-squared returned an impossible value.");
    return NULL;
}*/

/* Build the output tuple */
return PyArray_Return(result);
//PyObject *ret = Py_BuildValue("d", result);
//return ret;

}

static PyMethodDef module_methods[] = {
{"chie", chi2_chi2, METH_VARARGS, chie_docstring},
{NULL, NULL, 0, NULL}
};

static struct PyModuleDef cieModule = {
PyModuleDef_HEAD_INIT,
"cieModule",
"example Module",
-1,
module_methods
};

/*PyMODINIT_FUNC PyInit_myexamp_Module(void)
{
return PyModule_Create(&myexamp_Module);
import_array();
}
*/
PyMODINIT_FUNC PyInit_cieModule(void)
{
PyObject *m;
m = PyModule_Create(&cieModule);
if (!m) {
return NULL;
}
import_array();
return m;
}

@burbilog

This comment has been minimized.

Copy link

burbilog commented Sep 19, 2019

Great!

@NMO13

This comment has been minimized.

Copy link

NMO13 commented Sep 26, 2019

Really nice!

@Doug3579

This comment has been minimized.

Copy link

Doug3579 commented Nov 15, 2019

This demo seems to be written for macintosh. Will it works on Windows? Either way, it would be helpful to mention it in the readme and possibly in the title.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.