Python: using a module written in C
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:
#includestatic 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
>>>