编写python扩展模块_使用C++编写Python扩展

Python的很多库中都包含了C/C++的代码,在安装这种库的时候,尝尝会遇到这样的报错:error: unable to find vcvarsall.bat

通常的解决方案有两种:安装visual studio或者mingw;

使用编译好的Python库文件,进行安装。

一般大家都会选择安装编译过的库文件,或者安装mingw,但是如果要在Windows下为自己的Python程序编写扩展,安装visual studio是最优的解决方案。

下面介绍使用C++编写Python扩展模块的常见写法。

传入有限个数据

先建立一个Exten.cpp文件,编写如下代码:#include "Python.h"// 函数主体int add(int a,int b) {    return a + b;

}// 包裹函数static PyObject *Exten_add(PyObject *self,PyObject *args) {    int a,b;    // 获取数据,i代表int,ii代表两个int

// 如果没有获取到,则返回NULL

if (!PyArg_ParseTuple(args,"ii",&a,&b)) {        return NULL;

}    return (PyObject*)Py_BuildValue("i",add(a,b));

}// 添加PyMethodDef ModuleMethods[]数组static PyMethodDef ExtenMethods[] = {    // add:可用于Python调用的函数名,Exten_add:C++中对应的函数名

{"add",Exten_add,METH_VARARGS},

{NULL,NULL},

};// 初始化函数static struct PyModuleDef ExtenModule = {

PyModuleDef_HEAD_INIT,    "Exten",//模块名称

NULL,    -1,

ExtenMethods

};void PyInit_Exten() {

PyModule_Create(&ExtenModule);

}

再在同文件夹下建立setup.py文件,编写如下代码:from distutils.core import setup,Extension

MOD = 'Exten' #模块名setup(name=MOD,ext_modules=[Extension(MOD,sources=['D:\\Exten.cpp'])])

然后在CMD控制台输入:python D:\\setup.py build

python D:\\setup.py install

此模块便已经安装成功了。可以直接在Python代码中调用:>>> import Exten>>> Exten.add(1,3)4

传入可迭代对象

这种方式只能处理单个数据传入的任务,如果需要处理批量数组等批量数据,则需要涉及到Python对象到C++对象的转化。

以max函数为例,添加max函数之后,还需要为max编写包裹函数,整个Exten文件中代码如下:#include "Python.h"#include #define INT_MIN -2147483648using namespace std;// 函数主体int add(int a,int b) {    return a + b;

}int max(vector lst) {    int max_num = INT_MIN;    for (int i =0; i max_num) {

max_num = lst[i];

}

}    return max_num;

}// 包裹函数static PyObject *Exten_add(PyObject *self,PyObject *args) {    int a,b;    // 如果没有获取到数据

if (!PyArg_ParseTuple(args,"ii",&a,&b)) {        return NULL;

}    return (PyObject*)Py_BuildValue("i",add(a,b));

}// 模块中每个可供Python调用的函数都需要一个对应的包裹函数static PyObject *Exten_max(PyObject *self,PyObject *args) {

PyObject *obj;    vector lst;    // O代表对象

if (!PyArg_ParseTuple(args,"O",&obj)) {        return NULL;

}    // 获取可迭代对象

PyObject *iter = PyObject_GetIter(obj);    if (!iter) {

PyErr_SetString(PyExc_TypeError,"The object is not iterable!");        return NULL;

}    while (true) {        // 逐个获取列表中的各个元素

PyObject *next = PyIter_Next(iter);        if (!next) {            break;

}        // 检查是否为long或者long的子类(包括int)

if (!PyLong_Check(next)) {

PyErr_SetString(PyExc_TypeError,"Int or Long list is expected!");            return NULL;

}        // 由Python的Long转化为C/C++的long

long num = PyLong_AsLong(next);

lst.push_back(num);

}    return (PyObject*)Py_BuildValue("i",max(lst));

}// 添加PyMethodDef ModuleMethods[]数组static PyMethodDef ExtenMethods[] = {    // add:可用于Python调用的函数名,Exten_add:C++中对应的函数名

{"add",Exten_add,METH_VARARGS},

{"max",Exten_max,METH_VARARGS},

{NULL,NULL},

};// 初始化函数static struct PyModuleDef ExtenModule = {

PyModuleDef_HEAD_INIT,    "Exten",//模块名称

NULL,    -1,

ExtenMethods

};void PyInit_Exten() {

PyModule_Create(&ExtenModule);

}

采取同样的方式build + install之后,就可以使用了:>>> import Exten>>> Exten.max([1,2,3,4])4>>> Exten.max([1,2,3,4.1])

Traceback (most recent call last):

File "", line 1, in 

TypeError: Int or Long list is expected!

作者:dalalaa

链接:https://www.jianshu.com/p/eb2618067eae

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值