Copyright (C) 2000-2012 |
GNU Info (python2.1-ext.info)Module's Method Table and Initialization FunctionThe 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 |