Компилятор не может найти Py InitModule(). является ли он устаревшим, и если да, то что я должен использовать?

Я пытаюсь написать расширение C для python. С кодом (ниже) я получаю предупреждение компилятора:

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))

любая помощь была бы очень, очень признательна.

2 ответов


код у вас будет работать в Python 2.x, но Py_InitModule больше не используется в Python 3.х. В настоящее время, вы создаете 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_<name> здесь <name> - имя вашего модуль.

Я думаю, было бы полезно, если бы вы прочитали расширения в Python 3.х документации. Он имеет подробное описание того, как создавать модули расширения в современном Python.


Я столкнулся с той же проблемой с Py_InitModule(). Я начал с вышеупомянутых документов Python 3, в частности с документа" расширение и внедрение интерпретатора Python". Но в главе этого документа, озаглавленной "простой пример", отсутствуют детали. Так. Я прогуглил эту лекцию scipy:

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

что во многом больше подходит для кого-то нового для расширений API Python-C ... разве она не была обновлена для Python В3. Так. .. проконсультируйтесь с лекцией scipy и документами Python 3, и это обсуждение StackOverflow, отбирая соответствующую информацию из каждого для ваших нужд.