GNU Info

Info Node: (python2.1-ext.info)A Simple Example

(python2.1-ext.info)A Simple Example


Next: Intermezzo Errors and Exceptions Prev: Extending Python with C or C++ Up: Extending Python with C or C++
Enter node , (file) or (file)node

A Simple Example
================

Let's create an extension module called `spam' (the favorite food of
Monty Python fans...) and let's say we want to create a Python
interface to the C library function `system()'.(1) This function takes
a null-terminated character string as argument and returns an integer.
We want this function to be callable from Python as follows:

     >>> import spam
     >>> status = spam.system("ls -l")

Begin by creating a file `spammodule.c'.  (Historically, if a module is
called `spam', the C file containing its implementation is called
`spammodule.c'; if the module name is very long, like `spammify', the
module name can be just `spammify.c'.)

The first line of our file can be:

     #include <Python.h>

which pulls in the Python API (you can add a comment describing the
purpose of the module and a copyright notice if you like).

All user-visible symbols defined by `"Python.h"' have a prefix of `Py'
or `PY', except those defined in standard header files.  For
convenience, and since they are used extensively by the Python
interpreter, `"Python.h"' includes a few standard header files:
`<stdio.h>', `<string.h>', `<errno.h>', and `<stdlib.h>'.  If the
latter header file does not exist on your system, it declares the
functions `malloc()', `free()' and `realloc()' directly.

The next thing we add to our module file is the C function that will be
called when the Python expression `spam.system(STRING)' is evaluated
(we'll see shortly how it ends up being called):

     static PyObject *
     spam_system(self, args)
         PyObject *self;
         PyObject *args;
     {
         char *command;
         int sts;
     
         if (!PyArg_ParseTuple(args, "s", &command))
             return NULL;
         sts = system(command);
         return Py_BuildValue("i", sts);
     }

There is a straightforward translation from the argument list in Python
(e.g. the single expression `"ls -l"') to the arguments passed to the C
function.  The C function always has two arguments, conventionally
named SELF and ARGS.

The SELF argument is only used when the C function implements a
built-in method, not a function. In the example, SELF will always be a
`NULL' pointer, since we are defining a function, not a method.  (This
is done so that the interpreter doesn't have to understand two
different types of C functions.)

The ARGS argument will be a pointer to a Python tuple object containing
the arguments.  Each item of the tuple corresponds to an argument in
the call's argument list.  The arguments are Python objects -- in order
to do anything with them in our C function we have to convert them to C
values.  The function `PyArg_ParseTuple()' in the Python API checks the
argument types and converts them to C values.  It uses a template
string to determine the required types of the arguments as well as the
types of the C variables into which to store the converted values.
More about this later.

`PyArg_ParseTuple()' returns true (nonzero) if all arguments have the
right type and its components have been stored in the variables whose
addresses are passed.  It returns false (zero) if an invalid argument
list was passed.  In the latter case it also raises an appropriate
exception so the calling function can return `NULL' immediately (as we
saw in the example).

---------- Footnotes ----------

(1) An interface for this function already exists in the standard
module `os' -- it was chosen as a simple and straightfoward example.


automatically generated by info2www version 1.2.2.9