IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
1.1 A Simple Example


1.1 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.1This 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).

Warning: Since Python may define some pre-processor definitions which affect the standard headers on some systems, you must include Python.h before any standard headers are included.

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(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);
}

There is a straightforward translation from the argument list in Python (for example, 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

...system().1.1
An interface for this function already exists in the standard module os -- it was chosen as a simple and straightforward example.
See About this document... for information on suggesting changes.