问题
I am attempting to write a C extension for python. With the code (below) I get the compiler warning:
implicit declaration of function ‘Py_InitModule’
And it fails at run time with this error:
undefined symbol: Py_InitModule
I have spent literally hours searching for a solution with no joy. I have tried multiple minor changes to syntax, I even found a post suggesting the method has been deprecated. However I find no replacement.
Here is the code:
#include <Python.h>
//a func to calc fib numbers
int cFib(int n)
{
if (n<2) return n;
return cFib(n-1) + cFib(n-2);
}
static PyObject* fib(PyObject* self,PyObject* args)
{
int n;
if (!PyArg_ParseTuple(args,"i",&n))
return NULL;
return Py_BuildValue("i",cFib(n));
}
static PyMethodDef module_methods[] = {
{"fib",(PyCFunction) fib, METH_VARARGS,"calculates the fibonachi number"},
{NULL,NULL,0,NULL}
};
PyMODINIT_FUNC initcModPyDem(void)
{
Py_InitModule("cModPyDem",module_methods,"a module");
}
If it helps here is my setup.py :
from distutils.core import setup, Extension
module = Extension('cModPyDem', sources=['cModPyDem.c'])
setup(name = 'packagename',
version='1.0',
description = 'a test package',
ext_modules = [module])
And the test code in test.py :
import cModPyDem
if __name__ == '__main__' :
print(cModPyDem.fib(200))
Any help would be much, much appreciated.
回答1:
The code you have would work fine in Python 2.x, but Py_InitModule
is no longer used in Python 3.x. Nowadays, you create a PyModuleDef structure and then pass a reference to it to PyModule_Create.
The structure would look like:
static struct PyModuleDef cModPyDem =
{
PyModuleDef_HEAD_INIT,
"cModPyDem", /* name of module */
"", /* module documentation, may be NULL */
-1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
module_methods
};
And then your PyMODINIT_FUNC
function would look like:
PyMODINIT_FUNC PyInit_cModPyDem(void)
{
return PyModule_Create(&cModPyDem);
}
Note that the name of the PyMODINIT_FUNC
function must be of the form PyInit_<name>
where <name>
is the name of your module.
I think it would be worthwhile if you read Extending in the Python 3.x documentation. It has a detailed description of how to build extension modules in modern Python.
回答2:
I ran into the same problem with Py_InitModule(). I started with the aforementioned Python 3 docs, specifically the "Extending and Embedding the Python Interpreter" doc. But that doc's chapter entitled "A Simple Example" leaves out details. So. I googled this scipy lecture:
http://www.scipy-lectures.org/advanced/interfacing_with_c/interfacing_with_c.html
which is in many ways more suitable for someone new to Python-C API extensions ... except it has not been updated for Python v3. So ... consult the scipy lecture, and the Python 3 docs, and this StackOverflow discussion, culling the pertinent information from each for your needs.
来源:https://stackoverflow.com/questions/28305731/compiler-cant-find-py-initmodule-is-it-deprecated-and-if-so-what-should-i