Невозможно импортировать модуль Python, написанный на C

Я пытался понять, как создать файл .pyd (Python Extension Module) из сценария C (без swig или чего-либо еще, кроме MinGW), и успешно встроил его в .pyd.

Однако проблема возникает, когда я пытаюсь импортировать модуль.

Если я запускаю его, модуль запускается успешно (насколько я понимаю), а затем появляется сообщение об ошибке Python Has Stopped Working, и он закрывается, не выполняя остальную часть программы.

Вот мой сценарий C (test.c):

#include <python.h>

int main()
{
    PyInit_test();
    return 0;
}

int PyInit_test()
{
    printf("hello world");
}

И скрипт Python (file.py):

import test
print('Run From Python Extension')

Я скомпилировал скрипт с помощью:

gcc -c file.py
gcc -shared -o test.pyd test.c

Я не могу найти никаких ошибок при компиляции в командной строке и использую python 3.6 (работает в Windows 10).

Я не могу найти много информации по этой теме и предпочел бы держаться подальше от Cython (я уже знаю C) и Swig.

Любая помощь, чтобы сказать мне, что не так, была бы фантастической.


person Simon    schedule 14.08.2017    source источник
comment
Находится ли .pyd файл в той же папке, что и сценарий Python, который пытается import его выполнить? Python ищет модули определенным образом в определенных местах, и может быть просто вашей библиотеки нет ни в одном из тех мест, где он ищет. См. Создание расширений C и C ++ в документации.   -  person martineau    schedule 14.08.2017
comment
Функция инициализации вашего модуля не делает ни малейшей попытки инициализировать модуль. У него даже нет правильного возвращаемого типа. Вы вообще читали документы?   -  person user2357112 supports Monica    schedule 14.08.2017
comment
@martineau Я поместил .pyd в ту же папку, что и скрипт python, из которого я пытался его импортировать. Это заставило меня задуматься, и я поместил это в Lib. Отсюда я смог импортировать его, не получив ошибки, однако «привет, мир» не печатал просто «завершено»   -  person Simon    schedule 14.08.2017


Ответы (1)


Создание расширения Python полностью отличается от написания обычного кода C. Вы просто создали действительную программу на C, но это не имеет смысла для Python.

Вот как должна выглядеть ваша программа (это просто скелет, а не правильный рабочий код):

#include <Python.h>
#include <stdlib.h>

static PyObject* test(PyObject* self, PyObject* args)
{
    printf("hello world");
    return NULL;
}

static PyMethodDef test_methods[] = {
    {"test", test, METH_VARARGS, "My test method."},
    {NULL, NULL, 0, NULL} /* Sentinel */
};

PyMODINIT_FUNC init_test_methods() {
    Py_InitModule("test", test_methods);
}

int main(int argc, char** argv)
{
    /* Pass argv[0] to the Python interpreter */
    Py_SetProgramName(argv[0]);

    /* Initialize the Python interpreter. Required. */
    Py_Initialize();

    /* Add a static module */
    init_test_methods();
}

Я рекомендую вам узнать больше об этом по следующей ссылке: http://dan.iel.fm/posts/python-c-extensions/, а также в официальные документы.

person Matheus Portela    schedule 14.08.2017
comment
В этом есть большой смысл. Спасибо за помощь. Как вы говорите, это другое, как насчет компиляции, что все в порядке, или мне нужно сделать что-то другое, чтобы скомпилировать ее (сценарий установки)? - person Simon; 14.08.2017
comment
В составлении секрета нет. Если хотите, взгляните на этот мой проект, в котором я реализовал Caesar Cipher на C и предоставил для него расширение Python: github.com/matheusportela/caesar-cipher - person Matheus Portela; 15.08.2017
comment
Это решило проблему компиляции и дает мне фантастический пример для изучения. Что касается компиляции, это setup.py build не то, о чем я говорил ранее. Еще раз спасибо ¦] - person Simon; 15.08.2017
comment
И последнее замечание: setup.py build продолжает генерировать сообщение об ошибке unable to find vcvarsall.bat Я использовал -c mingw32 флаг в конце. Это дало еще одну ошибку Неизвестная версия компилятора MS версии 1900, которая была решена здесь И это наконец то компилировалось. - person Simon; 17.08.2017
comment
Отлично, @Simon! Поскольку я обычно не программирую в Windows, я не знал об этой проблеме. Приятно знать, что вы все поняли. - person Matheus Portela; 17.08.2017