This is a brief tutorial for using a module written in C inside a Python program. It’s a summarized recipe fr those who want to run and test something fast without falling in reading the docs, but I recommend to read.
[1] http://docs.python.org/extending/extending.html
[2] http://docs.python.org/extending/building.html
Let’s write a module called spam, the same as the example in [1], our spammodule.c will look like this:
#include
static PyObject *SpamError;
static PyObject *
spam_system(PyObject *self, PyObject *args){
const char *command;
int sts;
if (!PyArg_ParseTuple(args, “s”, &command))
return NULL;
sts = system(command);
return Py_BuildValue(”i”, sts);
}
static PyMethodDef SpamMethods[] = {
{”system”, spam_system, METH_VARARGS,
“Execute a shell command.”},
{NULL, NULL, 0, NULL} /* Sentinel */
};
PyMODINIT_FUNC
initspam(void){
PyObject *m;
m = Py_InitModule(”spam”, SpamMethods);
if (m == NULL)
return;
SpamError = PyErr_NewException(”spam.error”, NULL, NULL);
Py_INCREF(SpamError);
PyModule_AddObject(m, “error”, SpamError);
}
Ok, now, rather than compiling it by hand, let’s use an automated mechanism: distutils [2]. Edit a setup.py file which will be the “driver” for compile and make yur module in C importable from Python.
from distutils.core import setup, Extension
module1 = Extension('spam', sources = ['spammodule.c'])
setup(name = ‘PackageName’, version = ‘1.0′, description = ‘This is a demo package’,
ext_modules = [module1])
Compile the C module using the driver: $ python setup.py build
An example of the output I get:
running build
running build_ext
building 'spam' extension
creating build
creating build/temp.linux-x86_64-2.6
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.6 -c spammodule.c -o build/temp.linux-x86_64-2.6/spammodule.o
creating build/lib.linux-x86_64-2.6
gcc -pthread -shared build/temp.linux-x86_64-2.6/spammodule.o -L/usr/lib -lpython2.6 -o build/lib.linux-x86_64-2.6/spam.so
Test it!, depending on your platform and settings you’ll get a directory tree created, I’ll cd into mine:
$ cd build/lib.linux-x86_64-2.6
$ python
>>> import spam
>>> spam.system('echo "hello world"')
hello world
0
>>>