- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我刚刚开始尝试用 C 编写我的第一个 Python 扩展模块,并使用 https://www.tutorialspoint.com/python/python_further_extensions.htm 提供的说明。
我在 Linux Mint 18.1 上,在其 virtualenv 版本中使用 Python 3.6.1。
作为第一步,我编译了我计划编写的 Python 模块的一个非常简约的版本。
这是我的 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");
}
这里是我用来将 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'])])
令我惊讶的是,该模块在导入时无法正确加载:
>>> 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?
这里的构建协议(protocol)带有关于隐式声明 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
最佳答案
不再使用 Py_InitModule (Py_InitModule3)。有必要改为创建 PyModuleDef 结构,然后将对它的引用传递给 PyModule_Create。
在导入时创建的模块不会抛出错误的 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);
}
这里是构建协议(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
和成功导入的交互式 Python 控制台 session :
>>> 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')"
>>>
关于python - C++ Python模块导入错误: "undefined symbol: Py_InitModule3" ( Py_InitModule () ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43621948/
当我使用 Py_InitModule 注册回调时,如果我稍后更改结构中的函数指针以指向新函数,则会调用新函数。但是,如果我更改名称,则无法识别新名称。 #include PyObject* foo1
我正在尝试为 python 编写一个 C 扩展。使用代码(如下)我得到编译器警告: implicit declaration of function ‘Py_InitModule’ 它在运行时失败并出
我一直在关注一些关于如何为 Python 构建 C 模块的代码示例,但是 Py_InitModule 似乎没有在任何地方定义。 大多数消息来源说它在 modsupport.h 文件中,但宏没有在那里定
我刚刚开始尝试用 C 编写我的第一个 Python 扩展模块,并使用 https://www.tutorialspoint.com/python/python_further_extensions.h
我正在过渡到删除代码中的 boost-python 依赖项,并且我已经完成了此过渡的“最后一步”(我删除了所有其他 boost 依赖项,当我注释掉下面的 boost 代码时,我得到ImportErro
我想将我的 Python 版本从 2.7 更新到 3.5。 编译使用 PyString_InternFromString 和此 Py_InitModule 的代码时 我收到错误信息: Error
我是一名优秀的程序员,十分优秀!