Я пытаюсь узнать, как добавить C расширения.Я написал этот простой модуль с единственной функцией add_one, которая получает int n и возвращает n + 1.Файл C:
#include <Python.h>
static int add_one(int n){
return n + 1;
}
static PyObject* py_add_one(PyObject* self, PyObject* arg){
int n;
int res;
PyArg_ParseTuple(arg, "i", &n);
res = add_one(n);
return Py_BuildValue("i", res);
}
static PyMethodDef add_one_methods[] = {
{"add_one", py_add_one, METH_VARARGS, "example"},
{NULL}
};
static PyObject* init_add_one(void) {
PyObject* module = Py_InitModule("add_one", add_one_methods);
return module;
}
(*) Я знаю, что могу обойтись без функции add_one, но я оставляю это так, чтобы убедиться, что я правильно понял принципы и принципы.
А это мой setup.py:
from setuptools import setup, Extension
ext_modules = \
[Extension('add_one',
sources=['add_one.c'])]
setup(name='add_one',
ext_modules=ext_modules)
После того, как я установил пакет, запустив:
python setup.py install
и попытался его использовать, я получаю эту ошибку:
[root@c-141-87-1-005 ~]# python
Python 2.7.15 (default, Oct 15 2018, 18:36:25)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import add_one
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "build/bdist.linux-x86_64/egg/add_one.py", line 7, in <module>
File "build/bdist.linux-x86_64/egg/add_one.py", line 6, in __bootstrap__
ImportError: dynamic module does not define init function (initadd_one)
Я попытался переименовать init_add_one в initadd_one, но я все еще получил ту же ошибку.
РЕДАКТИРОВАТЬ: правильный файл C (нужно было добавить функцию PyMODINIT_FUNC, я также переименовал мой модуль в Пример):
#include <Python.h>
static int add_one(int n){
return n + 1;
}
static PyObject* py_add_one(PyObject* self, PyObject* arg){
int n;
int res;
PyArg_ParseTuple(arg, "i", &n);
res = add_one(n);
return Py_BuildValue("i", res);
}
static PyMethodDef methods[] = {
{"add_one", py_add_one, METH_VARARGS, "example"},
{NULL}
};
PyMODINIT_FUNC
initExample(void) {
(void) Py_InitModule("Example", methods);
}
и вот файл setup.py для него:
from setuptools import setup, Extension
ext_modules = \
[Extension('Example',
sources=['example.c'])]
setup(name='Example',
ext_modules=ext_modules)