Extending and Embedding Python, Release 3.9.5 9 2.1. Extending Python with C or C++ Note that PyMODINIT_FUNC declares the function as PyObject * return type, declares any special linkage declarations required by the platform, and for C++ declares the function as$_{extern "C"}$ . return PyLong_FromLong(sts); In this case, it will return an integer object. (Yes, even integers are objects on the heap in Python!) If you have a C function that returns no useful argument (a function returning $_{void}$), the corresponding Python function must return$_{None}$ . You need this idiom to do so (which is implemented by the$_{Py_RETURN_NONE}$ macro): Py_INCREF(Py_None); return Py_None; Py_None is the C name for the special Python object $_{None}$. It is a genuine Python object rather than a NULL pointer, which means “error” in most contexts, as we have seen. 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”: 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 referenced in the module definition structure: This structure, in turn, must be passed to the interpreter in the module’s initialization function. The initialization function must be named$_{PyInit_name()}$ , where name is the name of the module, and should be the only non- $_{static}$item defined in the module file: PyMODINIT_FUNC PyInit_spam( void ) { return PyModule_Create( &spammodule); } static structPyModuleDef spammodule={ PyModuleDef_HEAD_INIT, "spam", /* name of module */ spam_doc, /* module documentation, may be NULL */ -1 , /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ SpamMethods }; static PyMethodDef SpamMethods[] ={ ... { "system", spam_system, METH_VARARGS, "Execute a shell command. "}, ... { NULL ,NULL ,0,NULL } /* Sentinel */ }; 2.1.4 The Module’s Method Table and Initialization Function