我正在尝试学习如何添加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函数,我也将模块重命名为Example):
#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)