[英]C++ Python module import error: “undefined symbol: Py_InitModule3” ( Py_InitModule () )
I am just starting an attempt to write my first Python extension module in C and are using instructions provided at https://www.tutorialspoint.com/python/python_further_extensions.htm 我刚开始尝试在C中编写我的第一个Python扩展模块,并使用https://www.tutorialspoint.com/python/python_further_extensions.htm中提供的说明。
I am on Linux Mint 18.1, using Python 3.6.1 in its virtualenv version. 我在Linux Mint 18.1上,在其virtualenv版本中使用Python 3.6.1。
As first step I have compiled a very minimalistic version of the Python module I plan to write. 作为第一步,我编写了一个非常简约的Python模块版本。
Here my C-code: 这是我的C代码:
include <Python.h>
static PyObject* uniqueCombinations(PyObject* self)
{
return Py_BuildValue("s", "uniqueCombinations() return value (is of type 'string')");
}
static char uniqueCombinations_docs[] =
"usage: uniqueCombinations(lstSortableItems, comboSize)\n";
static PyMethodDef uniqueCombinations_funcs[] = {
{"uniqueCombinations", (PyCFunction)uniqueCombinations,
METH_NOARGS, uniqueCombinations_docs},
{NULL}
};
void inituniqueCombinations(void)
{
Py_InitModule3("uniqueCombinations", uniqueCombinations_funcs,
"Extension module uniqueCombinations v. 0.01");
}
and here the code of the setup.py file I have used to compile the C-code to uniqueCombinations.cpython-36m-x86_64-linux-gnu.so
: 这里是我用来编译C代码到uniqueCombinations.cpython-36m-x86_64-linux-gnu.so
的setup.py文件的代码:
from distutils.core import setup, Extension
setup(name='uniqueCombinations', version='0.01', \
ext_modules=[Extension('uniqueCombinations', ['uniqueCombinations_pythonCmodule_v-0.01_Cg.c'])])
To my surprise the module doesn't load properly on import: 令我惊讶的是,导入时模块无法正确加载:
>>> import uniqueCombinations
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: uniqueCombinations.cpython-36m-x86_64-linux-gnu.so: undefined symbol: Py_InitModule3
Why am I getting this error? 为什么我收到此错误?
And what should I do to be able to load the compiled module properly? 我该怎么做才能正确加载已编译的模块?
Here the build protocol with a warning about implicit declaration of Py_InitModule3 : 这里的构建协议带有关于Py_InitModule3的隐式声明的警告:
$ python uniqueCombinations_pythonCmodule_v-0.01_setup.py_Cg.py build
running build
running build_ext
building 'uniqueCombinations' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/usr/local/include/python3.6m -c uniqueCombinations_pythonCmodule_v-0.01_Cg.c -o build/temp.linux-x86_64-3.6/uniqueCombinations_pythonCmodule_v-0.01_Cg.o
uniqueCombinations_pythonCmodule_v-0.01_Cg.c: In function ‘inituniqueCombinations’:
uniqueCombinations_pythonCmodule_v-0.01_Cg.c:19:5: warning: implicit declaration of function ‘Py_InitModule3’ [-Wimplicit-function-declaration]
Py_InitModule3("uniqueCombinations", uniqueCombinations_funcs,
^
creating build/lib.linux-x86_64-3.6
gcc -pthread -shared build/temp.linux-x86_64-3.6/uniqueCombinations_pythonCmodule_v-0.01_Cg.o -o build/lib.linux-x86_64-3.6/uniqueCombinations.cpython-36m-x86_64-linux-gnu.so
The Py_InitModule (Py_InitModule3) is no longer used. 不再使用Py_InitModule(Py_InitModule3)。 It is necessary to create a PyModuleDef structure instead and then pass a reference to it to PyModule_Create. 有必要改为创建PyModuleDef结构,然后将对它的引用传递给PyModule_Create。
Below the C-code from which created module doesn't throw an error when imported: 在导入时创建的模块不会引发错误的C代码下面:
#include <Python.h>
static PyObject* uniqueCombinations(PyObject* self)
{
return Py_BuildValue("s", "uniqueCombinations() return value (is of type 'string')");
}
static char uniqueCombinations_docs[] =
"usage: uniqueCombinations(lstSortableItems, comboSize)\n";
/* deprecated:
static PyMethodDef uniqueCombinations_funcs[] = {
{"uniqueCombinations", (PyCFunction)uniqueCombinations,
METH_NOARGS, uniqueCombinations_docs},
{NULL}
};
use instead of the above: */
static PyMethodDef module_methods[] = {
{"uniqueCombinations", (PyCFunction) uniqueCombinations,
METH_NOARGS, uniqueCombinations_docs},
{NULL}
};
/* deprecated :
PyMODINIT_FUNC init_uniqueCombinations(void)
{
Py_InitModule3("uniqueCombinations", uniqueCombinations_funcs,
"Extension module uniqueCombinations v. 0.01");
}
*/
static struct PyModuleDef Combinations =
{
PyModuleDef_HEAD_INIT,
"Combinations", /* name of module */
"usage: Combinations.uniqueCombinations(lstSortableItems, comboSize)\n", /* 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
};
PyMODINIT_FUNC PyInit_Combinations(void)
{
return PyModule_Create(&Combinations);
}
Here the build protocol: 这里的构建协议:
$ python uniqueCombinations_pythonCmodule_v-0.01_setup.py_Cg.py build
running build
running build_ext
building 'Combinations' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/usr/local/include/python3.6m -c uniqueCombinations_pythonCmodule_v-0.01_Cg.c -o build/temp.linux-x86_64-3.6/uniqueCombinations_pythonCmodule_v-0.01_Cg.o
gcc -pthread -shared build/temp.linux-x86_64-3.6/uniqueCombinations_pythonCmodule_v-0.01_Cg.o -o build/lib.linux-x86_64-3.6/Combinations.cpython-36m-x86_64-linux-gnu.so
and the interactive Python console session with successful import: 和成功导入的交互式Python控制台会话:
>>> import Combinations
>>> dir(Combinations)
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'uniqueCombinations']
>>> Combinations.__doc__
'usage: Combinations.uniqueCombinations(lstSortableItems, comboSize)\n'
>>> Combinations.uniqueCombinations()
"uniqueCombinations() return value (is of type 'string')"
>>>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.