当Python与您的系统紧密互动时,易于编程的Python变得非常强大,为此,他与这个叫C的人变得友好起来。
Python使用C建立紧密绑定的包装器,以便它可以扩展C API,并与系统接口建立更紧密的关系。通过在C代码中使用PyObjects来实现python的包装器,可以轻松区分C语言中的python代码。 C文件,因为大多数python对象和API都以Py或PY开头。
在为C函数编写python包装器的过程中,出现以下步骤
#myadd.c
int add(int a, int b)
{
return a+b;
}
这个简单的C函数接受两个参数并调和它们的和
#wrapping.c
#include <python2.4 / Python.h>
第一步将包括一个Python标头,其中包含一些必要的命令,例如stdio.h,string.h ...
第二步是将函数参数从Python转换为C,并以Python友好的形式返回结果。
PyObject *wrap_add(PyObject *self, PyObject *args) {
int a,b,result;
if (!PyArg_ParseTuple(args,"ii",&a,&b))
return NULL;
result = add(a,b);
return Py_BuildValue("i",result);
}
python wrap函数具有两个PyObject参数self和args。
当C实现包含参数的python元组的内置函数和args时,将使用self
Python和C之间的数据转换使用两个函数执行:
int PyArg_ParseTuple(PyObject * args,char * format,...)
PyObject * Py_BuildValue(char *格式,...)
PyArg_ParseTuple是一个python API,用于检查传递的参数类型,是否正确存储在内存中,如果错误则返回null.Py_BuildValue从C函数以python形式返回结果。
在我们的例子中,add接受两个参数,这些参数传递给PyArg_ParseTuple,然后调用C函数add,并将值存储在整数结果中,使用Py_BuildValue进行检索
最后一步是让解释器了解我们已经实现了包装器,我们使用函数将其初始化
static PyMethodDef exampleMethods[] = {
{ "add", wrap_add, METH_VARARGS,"A simple addition program" },
{ NULL, NULL, 0, NULL }
};
void initmyadd() {
PyObject *m;
m = Py_InitModule("myadd", exampleMethods);
}
在PyMethodDef中,第一个值是我想为python中的方法提供的名称(U可以使用不同的名称而不是add)。METH_VARARGS是一个标志,告诉解释器用于C函数的调用约定第四个是doc字符串。
首次调用myadd时,它将调用initmyadd,这将创建一个模块对象(将其插入到字典sys.modules中的键“ myadd”下),并根据该对象将内置函数对象插入到新创建的模块中。作为第二个参数传递的表(PyMethodDef结构的数组)。 初始化错误时Py_InitModule()返回null。PyMODINIT_FUNC API用于void返回类型函数声明。
From: https://bytes.com/topic/python/insights/790600-extending-python