【问题标题】:Compiler can't find Py_InitModule() .. is it deprecated and if so what should I use?编译器找不到 Py_InitModule() .. 它是否已弃用,如果是,我应该使用什么?
【发布时间】:2015-04-03 01:13:56
【问题描述】:

我正在尝试为 python 编写一个 C 扩展。使用代码(如下)我得到编译器警告:

implicit declaration of function ‘Py_InitModule’

它在运行时失败并出现此错误:

undefined symbol: Py_InitModule

我花了好几个小时寻找一个没有乐趣的解决方案。我已经尝试了对语法的多次细微更改,我什至发现了一个帖子表明该方法已被弃用。但是我找不到替代品。

代码如下:

#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");
}

如果有帮助,这里是我的 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])

以及 test.py 中的测试代码:

import cModPyDem

if __name__ == '__main__' :

    print(cModPyDem.fib(200))

任何帮助将不胜感激。

【问题讨论】:

  • 你编译的 Python 版本是什么?
  • 对不起,我正在用 python3 编译

标签: python c python-extensions


【解决方案1】:

您的代码在 Python 2.x 中可以正常工作,但在 Python 3.x 中不再使用 Py_InitModule。现在,您创建了一个PyModuleDef 结构,然后将对它的引用传递给PyModule_Create

结构如下:

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
};

然后您的 PyMODINIT_FUNC 函数将如下所示:

PyMODINIT_FUNC PyInit_cModPyDem(void)
{
    return PyModule_Create(&cModPyDem);
}

请注意,PyMODINIT_FUNC 函数的名称必须采用 PyInit_&lt;name&gt; 的形式,其中 &lt;name&gt; 是您的模块的名称。

如果您阅读 Python 3.x 文档中的 Extending,我认为这将是值得的。它详细描述了如何在现代 Python 中构建扩展模块。

【讨论】:

  • 优秀 - 您提供的代码可以正常工作,除了一个小的更改 - PyMODINIT_FUNC PyInit_cModPyDem(void){} - 是正确的方法。谢谢,是的,值得阅读文档。
  • return PyModule_Create(&amp;ModPyDem); 中,正确的应该是return PyModule_Create(&amp;cModPyDem);?
  • 顺便说一句,这给出了“警告:Python 3.6.8 Ubuntu 18.04 中‘struct PyModuleDef’的字段‘m_slots’缺少初始化程序。
【解决方案2】:

我在 Py_InitModule() 中遇到了同样的问题。我从前面提到的 Python 3 文档开始,特别是“Extending and Embedding the Python Interpreter”文档。但是该文档的标题为“一个简单示例”的章节省略了细节。所以。我用谷歌搜索了这个 scipy 讲座:

http://www.scipy-lectures.org/advanced/interfacing_with_c/interfacing_with_c.html

这在很多方面更适合 Python-C API 扩展的新手……除了它没有针对 Python v3 进行更新。所以...请参阅 scipy 讲座、Python 3 文档和 StackOverflow 讨论,根据您的需要从每一个中挑选相关信息。

【讨论】:

    猜你喜欢
    • 2015-09-20
    • 2014-09-20
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    相关资源
    最近更新 更多