GNU Info

Info Node: (python2.1-ext.info)Module's Method Table and Initialization Function

(python2.1-ext.info)Module's Method Table and Initialization Function


Next: Compilation and Linkage Prev: Back to the Example Up: Extending Python with C or C++
Enter node , (file) or (file)node

The Module's Method Table and Initialization Function
=====================================================

I promised to show how `spam_system()' is called from Python programs.
First, we need to list its name and address in a "method table":

     static PyMethodDef SpamMethods[] = {
         ...
         {"system",  spam_system, METH_VARARGS},
         ...
         {NULL,      NULL}        /* Sentinel */
     };

Note the third entry (`METH_VARARGS').  This is a flag telling the
interpreter the calling convention to be used for the C function.  It
should normally always be `METH_VARARGS' or `METH_VARARGS |
METH_KEYWORDS'; a value of `0' means that an obsolete variant of
`PyArg_ParseTuple()' is used.

When using only `METH_VARARGS', the function should expect the
Python-level parameters to be passed in as a tuple acceptable for
parsing via `PyArg_ParseTuple()'; more information on this function is
provided below.

The `METH_KEYWORDS' bit may be set in the third field if keyword
arguments should be passed to the function.  In this case, the C
function should accept a third `PyObject *' parameter which will be a
dictionary of keywords.  Use `PyArg_ParseTupleAndKeywords()' to parse
the arguments to such a function.

The method table must be passed to the interpreter in the module's
initialization function.  The initialization function must be named
`initNAME()', where NAME is the name of the module, and should be the
only non-`static' item defined in the module file:

     void
     initspam()
     {
         (void) Py_InitModule("spam", SpamMethods);
     }

Note that for C++, this method must be declared `extern "C"'.

When the Python program imports module `spam' for the first time,
`initspam()' is called. (See below for comments about embedding
Python.)  It calls `Py_InitModule()', which creates a "module object"
(which is inserted in the dictionary `sys.modules' under the key
`"spam"'), and inserts built-in function objects into the newly created
module based upon the table (an array of `PyMethodDef' structures) that
was passed as its second argument.  `Py_InitModule()' returns a pointer
to the module object that it creates (which is unused here).  It aborts
with a fatal error if the module could not be initialized
satisfactorily, so the caller doesn't need to check for errors.

When embedding Python, the `initspam()' function is not called
automatically unless there's an entry in the `_PyImport_Inittab' table.
The easiest way to handle this is to statically initialize your
statically-linked modules by directly calling `initspam()' after the
call to `Py_Initialize()' or `PyMac_Initialize()':

     int main(int argc, char **argv)
     {
         /* Pass argv[0] to the Python interpreter */
         Py_SetProgramName(argv[0]);
     
         /* Initialize the Python interpreter.  Required. */
         Py_Initialize();
     
         /* Add a static module */
         initspam();

An example may be found in the file `Demo/embed/demo.c' in the Python
source distribution.

*Note:*  Removing entries from `sys.modules' or importing compiled
modules into multiple interpreters within a process (or following a
`fork()' without an intervening `exec()') can create problems for some
extension modules.  Extension module authors should exercise caution
when initializing internal data structures.  Note also that the
`reload()' function can be used with extension modules, and will call
the module initialization function (`initspam()' in the example), but
will not load the module again if it was loaded from a dynamically
loadable object file (`.so' on UNIX, `.dll' on Windows).

A more substantial example module is included in the Python source
distribution as `Modules/xxmodule.c'.  This file may be used as a
template or simply read as an example.  The `modulator.py' script
included in the source distribution or Windows install provides a
simple graphical user interface for declaring the functions and objects
which a module should implement, and can generate a template which can
be filled in.  The script lives in the `Tools/modulator/' directory;
see the `README' file there for more information.


automatically generated by info2www version 1.2.2.9