Info Node: (python2.1-ext.info)Module's Method Table and Initialization Function
(python2.1-ext.info)Module's Method Table and Initialization Function
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.