[Prophesy] C from Python Example

Daniel Phillips phillips at bonn-fries.net
Sun Jun 9 07:06:12 EST 2002


It's about time to try using some C code from Python, to see how well that 
works out.  If it does work out then I suppose we are on our way.  I'm 
guessing that the work will go several times faster in Python than in C, 
because of fewer worres about memory allocation and such things.

While the Python C api is well documented, the requirements for compiling and 
installing python loadable modules written in C aren't.  After a little 
guesswork and fiddling around I came up with the following simple example, 
which defines a class with one method that simply returns a copy of the 
string passed to it.

File foo.c:

  #include "Python.h"

  static PyObject *foobar(PyObject *self, PyObject *args)
  {
	char *string;
	return PyArg_Parse(args, "s", &string)? PyString_FromString(string): NULL;
  }

  static PyMethodDef foo_methods[] =
  {
	{"bar", foobar},
	{NULL, NULL}
  };

  void initfoo()
  {
	Py_InitModule("foo", foo_methods);
  }

Apparently PyArg_Parse is deprecated, but it works.  The new, improved way 
isn't a lot different, but I haven't tried it yet.

I must say, it's a little frightening that Python actually parses a string on 
every call to a C function.  Surely there is a better way of doing this.  For 
example, parse the strings at module load time.  The moral of the story is: 
don't expect Python to be fast, not with this kind of implementation.  Oh 
well, it still should work out well for this project, since the heavy lifting 
will be done in tightly coded C.

The example can be compiled, installed as a module, and executed using the 
script line:

  cc -shared -I/usr/include/python2.2 python2.c -o foo.so && \
  sudo cp foo.so /usr/lib/python2.2/lib-dynload/ && \
  python2.2 -c "import foo; print foo.bar('test')"

I verified that this example works in python 1.5, 2.1 and 2.2.  The 
python2.2-dev package has to be installed to get the Python.h header file.

I'd like to import the module without copying it to the lib-dynload 
directory, which is not a good way to develop because it requires root 
privilege, and anyway, it's an annoying extra step.  I'm sure there's a way 
to do it, but I haven't found it yet.

There is also a fancy system called 'distutils' that builds and installs 
extension modules.  I don't really see why anything fancier than what I've 
shown here is needed for development.

Reference material is available here:

   http://python.org/doc/current/ext/ext.html
   "Extending and Embedding the Python Interpreter"

   http://python.org/doc/current/api/api.html
   "Python/C API Reference Manual"

-- 
Daniel



More information about the Prophesy mailing list