Ошибка при создании модуля python

У меня есть код C, который вызывает подпрограмму Fortran, называемую SetFlags. Я хотел бы превратить этот код C в модуль Python. Он создает файл .so, но я не могу импортировать этот модуль в python. Я не уверен, что моя ошибка связана с созданием модуля с помощью distutils или с подключением к библиотеке fortran. Вот мой файл setflagsmodule.c

#include <Python/Python.h>
#include "/Users/person/program/x86_64-Darwin/include/Cheader.h"
#include <stdlib.h>
#include <stdio.h>

static char module_docstring[] = 
    "This module provides an interface for Setting Flags in C";

static char setflags_docstring[] = 
    "Set the Flags for program";



static PyObject * setflags(PyObject *self, PyObject *args)
{
    int *error;
    const int mssmpart;
    const int fieldren;
    const int tanbren;
    const int higgsmix;
    const int p2approx;
    const int looplevel;
    const int runningMT;
    const int botResum;
    const int tlcplxApprox;


    if (!PyArg_ParseTuple(args, "iiiiiiiiii", &error,&mssmpart,&fieldren,&tanbren,&higgsmix,&p2approx,&looplevel,&runningMT,&botResum,&tlcplxApprox))
        return NULL;

    FSetFlags(error,mssmpart,fieldren,tanbren,higgsmix,p2approx,looplevel,runningMT,botResum,tlcplxApprox); //Call fortran subroutine
    return Py_None;
}

static PyMethodDef setflags_method[] = {
    {"FSetFlags", setflags, METH_VARARGS, setflags_docstring},
    {NULL,NULL,0,NULL}
};

PyMODINIT_FUNC init_setflags(void)
{
    PyObject *m;
    m = Py_InitModule3("setflags", setflags_method, module_docstring);
        if (m == NULL)
            return;
}

Вот мой установочный файл с именем setflags.py:

    from distutils.core import setup, Extension

setup(
    ext_modules=[Extension("setflags",["setflagsmodule.c"], include_dirs=['/Users/person/program/x86_64-Darwin'],
    library_dirs=['/Users/person/program/x86_64-Darwin/lib/'], libraries=['FH'])],
    )

Я строю модуль, используя:

python setflags.py build_ext --inplace

Когда я пытаюсь импортировать модуль в python, это результат:

>>> import setflags
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initsetflags)

У кого-нибудь есть рекомендации о том, как решить эту ошибку ImportError?

Мы будем очень признательны за любую помощь и заранее благодарим вас за ваше время.


person user2461433    schedule 06.06.2013    source источник
comment
Вы пытались просто удалить все ссылки на Fortran и посмотреть, появится ли такая же ошибка? Это был бы очевидный способ исключить ваш вопрос.   -  person abarnert    schedule 07.06.2013
comment
Зачем возиться с упаковкой distutils, если у вас даже не запущен модуль? Сначала заставьте его работать, а потом уже беспокойтесь об упаковке.   -  person Lee Daniel Crocker    schedule 07.06.2013
comment
@LeeDanielCrocker: Многие люди не знают, как компилировать расширения C без distutils, потому что это первый (и единственный для POSIX) способ, которым учебник показывает вам, как это сделать. См. Компиляция и компоновка. И даже после того, как вы научитесь делать cc $(python-config --cflags) $(python-config --ldflags) foomodule.c -o foomodule.so, зачастую проще написать setup.py один раз и покончить с этим.   -  person abarnert    schedule 07.06.2013
comment
Интересно. Я никогда не мог понять, как заставить distutils работать с моей библиотекой. Но тогда я сначала программист на C.   -  person Lee Daniel Crocker    schedule 07.06.2013


Ответы (1)


Проблема очень простая, но ее легко пропустить.

Обратите внимание на ошибку, которую вы получаете:

ImportError: dynamic module does not define init function (initsetflags)

Теперь посмотрите на свой код:

PyMODINIT_FUNC init_setflags(void)

Вы определили init_setflags вместо initsetflags. Просто удалите дополнительное подчеркивание, и оно должно работать.


Из документации по Таблица методов модуля и функция инициализации:

Функция инициализации должна называться initname(), где name — имя модуля…


Причина, по которой вы часто видите init функции с именем init_foo в примерах, заключается в том, что они обычно инициализируют модуль _foo.so, который затем будет обернут чистым модулем Python foo.py.

person abarnert    schedule 06.06.2013
comment
Спасибо за помощь. Это решило проблему - person user2461433; 07.06.2013