c语言与python通信_python和c++通信示例

先贴一个大牛写的python与C++的通信的经典文章:如何实现 C/C++ 与 Python 的通信?

里面讲到了不少方法来实现C++和python之间的通信,我看了之后深有感触,但里面的例程序大多都是int或者string这样容易转换的,但如果是list呢,应该如何传递到C++中。

于是在stackoverflow上转了之后发现了这么一种方法,

PyObject *pList;

PyObject *pItem;

Py_ssize_t n;

int i;

if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &pList)) {

PyErr_SetString(PyExc_TypeError, "parameter must be a list.");

return NULL;

}

n = PyList_Size(pList);

for (i=0; i

pItem = PyList_GetItem(pList, i);

if(!PyInt_Check(pItem)) {

PyErr_SetString(PyExc_TypeError, "list items must be integers.");

return NULL;

}

}

"O!" (object)[typeobject, PyObject *]

将Python对象存储在C对象指针中。这类似于“O”,但是接受两个C参数:第一个是Python类型对象的地址,第二个是对象指针存储在其中的C变量(类型为PyObject *)的地址。如果Python对象没有所需的类型,就会引发类型错误(TypeError)。

Python的对象在底层的C语言中就是PyObject,通常用指针去表示也就是PyObject*.

看不懂没关系,直接往下看。

list本身也是个对象,于是"O!"的格式就能将list对应的那个对象的指针赋给pList.

但是我们得到list对象了,如何解析呢,毕竟里面有可能各种类型都有的。

我们必须了解list在C++中的函数库:

此时(假设你用的是linux+python2.7),打开/usr/include/python2.7

你就会看到一堆头文件。

大概就是这样,然后你会发现,里面有个叫listobject.h的东西,这个里头就是对list的一些声明。

#ifndef Py_LISTOBJECT_H

#define Py_LISTOBJECT_H

#ifdef __cplusplus

extern "C" {

#endif

typedef struct {

PyObject_VAR_HEAD

/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */

PyObject **ob_item;

/* ob_item contains space for 'allocated' elements. The number

* currently in use is ob_size.

* Invariants:

* 0 <= ob_size <= allocated

* len(list) == ob_size

* ob_item == NULL implies ob_size == allocated == 0

* list.sort() temporarily sets allocated to -1 to detect mutations.

*

* Items must normally not be NULL, except during construction when

* the list is not yet visible outside the function that builds it.

*/

Py_ssize_t allocated;

} PyListObject;

PyAPI_DATA(PyTypeObject) PyList_Type;

#define PyList_Check(op) \

PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS)

#define PyList_CheckExact(op) (Py_TYPE(op) == &PyList_Type)

PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size);

PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *);

PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t);

PyAPI_FUNC(int) PyList_SetItem(PyObject *, Py_ssize_t, PyObject *);

PyAPI_FUNC(int) PyList_Insert(PyObject *, Py_ssize_t, PyObject *);

PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *);

PyAPI_FUNC(PyObject *) PyList_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t);

PyAPI_FUNC(int) PyList_SetSlice(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);

PyAPI_FUNC(int) PyList_Sort(PyObject *);

PyAPI_FUNC(int) PyList_Reverse(PyObject *);

PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *);

PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *);

风格极度友好,纯C打造,不像某模板库源码天花乱坠。

因为看不到具体的实现,我们只能从声明里猜,还是很好猜的。

我们可以发现:

PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size);

这个肯定是创建的函数啦,显而易见。返回值是一个PyObject*.

PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t);

这个就是读取指定项的函数了,英文名也显而易见的。返回值也是PyObject*,毕竟list里面也都是对象,是对象就是PyObject。

PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *);

然后这个呢就是添加函数了,第一个参数是list指针,第二个是被你放入的新对象的指针。

然后是PyObject **ob_item,这个是定义在结构体里头的,熟悉C语言的就知道,指针的指针嘛,也就是list的头,所以看到这里你就应该知道,list里其实是装指针的。因为是C写的,所以也没有private属性,你想访问就访问。

其他函数就不解释了,你应该也看得懂。

接下来,如何用这几个函数处理呢?

回到之前那段代码里,有这么一句话:

PyArg_ParseTuple(args, "O!", &PyList_Type, &pList));

这个跑完之后,pList就是指向你的list的指针了。

然后我们要做的就是用PyList_GetItem把list中的每一个东西弄出来(简单起见,在python的代码里就别往list里丢一些乱七八糟的东西了,不然像前面那样得加一堆判断异常什么的,我们现在只放整数)

但这个整数传到C++中可不是整数,是PyObject,

void quick_sort(int *a,int length) {

std::sort(a,a+length);

}

/*

略去大段代码

*/

int *A=new int[n];

for (i=0; i

{

pItem = PyList_GetItem(pList, i);

A[i]=PyInt_AsLong(pItem);

}

quick_sort(A,n) ;

于是,我们得用PyInt_AsLong把每个我读取出来的item做一个转换,从python的整形转为C++的整形,存入我们开辟的空间A中。

然后调用std::sort即可。

但是我们得到了排完序的数组怎么返回给python呢?

PyObject *new_list;

new_list=PyList_New(0);

for(i=0;i

{

PyList_Append(new_list,PyInt_FromLong(A[i]) );

}

很简单,也是用listobject.h中的函数。先用PyList_New来new一个list,然后往里头加数据就可以了,不过你得加PyObject*才行,所以我们用

PyList_Append(new_list,PyInt_FromLong(A[i]) );

来做一个转换。

最后我们把new_list返回去就可以了。具体的一些别的细节如导入导出,编译请看文章首部的链接。

最后奉上完整代码:

这个是C++部分,你得把这编译成一个动态链接库(.so文件)

//文件名:sort.cpp#include #includevoid quick_sort(int *a,int length) {

std::sort(a,a+length);

}

static PyObject * _quick_sort(PyObject *self, PyObject *args)

{

PyObject *pList;

PyObject *new_list;

PyObject *pItem;

Py_ssize_t n;

int i;

PyArg_ParseTuple(args, "O!", &PyList_Type, &pList);

n = PyList_Size(pList);

new_list=PyList_New(0);

n=(int)n;

int *A=new int[n];

for (i=0; i

{

pItem = PyList_GetItem(pList, i);

A[i]=PyInt_AsLong(pItem);

}

quick_sort(A,n) ;

for(i=0;i

{

PyList_Append(new_list,PyInt_FromLong(A[i]) );

}

delete A;

return new_list;

}

static PyMethodDef SortMethods[] = {

{

"quick_sort",

_quick_sort,

METH_VARARGS,

""

},

{NULL, NULL, 0, NULL}

};

PyMODINIT_FUNC initsort(void) {

(void) Py_InitModule("sort", SortMethods);

}

命令是:g++ -fPIC -shared sort.cpp -o sort.so -I/usr/include/python2.7/ -lpython2.7

然后是python部分

#文件名:aa.py

from sort import quick_sort

a=[1,3,2,6,4,5,0,7]

b=quick_sort(a)

print(b)

命令是:python2 aa.py

最后就能看到输出啦:

[0, 1, 2, 3, 4, 5, 6, 7]

整个代码写下来其实没什么用,毕竟你要sort在python里sort一下,也没必要重复造轮子。

但是如果没有人去做这种工作,那某些深度学习框架中调用GPU的操作也就做不出来了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/258879.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

halcon/c++接口基础 之 控制参数

HALCON/C可以处理各种不同类型的字母数字混合的控制参数&#xff0c;如下&#xff1a; 离散数字&#xff08;long&#xff09;浮点数字&#xff08;double&#xff09;字符串&#xff08;char*&#xff09; 控制参数的一个特殊形式是句柄&#xff0c;提供了途径去访问复杂的数…

C#使用多态求方形面积周长和圆的面积周长

class class1{public static void Main(string[] args){//使用多态求矩形面积与周长和圆的面积与周长Shape cl new Circle(5);double clarea cl.GetArea();double clpar cl.GetPerimeter();Console.WriteLine("这个圆的面积是{0},周长是{1}", Math.Round(clarea, …

Java编程的逻辑 (84) - 反射

​本系列文章经补充和完善&#xff0c;已修订整理成书《Java编程的逻辑》&#xff0c;由机械工业出版社华章分社出版&#xff0c;于2018年1月上市热销&#xff0c;读者好评如潮&#xff01;各大网店和书店有售&#xff0c;欢迎购买&#xff0c;京东自营链接&#xff1a;http://…

C# 与 VC Dll 传输信息

考虑&#xff1a; 使用string类型传送&#xff1b; 在VC Dll中解析字符&#xff1b; 使用 string 类型将解析的类型传送到C#程序中&#xff1b; 建立VC解析的函数&#xff0c;提高代码可重用性转载于:https://www.cnblogs.com/ein-key5205/p/3597612.html

linux下python_linux下python安装

Python2.5的安装方法&#xff1a; 1&#xff0e;下载源代码 http://www.python.org/ftp/python/2.5.2/Python-2.5.2.tar.bz2 2&#xff0e; 安装 $ tar –jxvf Python-2.5.2.tar.bz2 $ cd Python-2.5.2 $ ./configure $ make $ make install 3. 测试 在命令行下输入python&…

灰度图像的8位平面分解

所谓灰度图像&#xff0c;即指8位256颜色的图像。将图像的每一位分别取出来&#xff0c;我们就可以将一幅图像分解开来&#xff0c;形成8幅图像。下面我们分别介绍使用matlab分解图像与使用halcon/c分解图像的方法。 matlab8位分解 clc; clear all; A imread(lena.tif); % 显…

Win10 UAP 绑定

Compiled DataBinding in Windows Universal Applications (UAP) http://nicksnettravels.builttoroam.com/post/2015/04/26/Compiled-DataBinding-in-Windows-Universal-Applications-(UAP).aspx 读写剪贴板 http://www.cnphp6.com/archives/80079 Learn how the Reversi samp…

HDUOJ----4501小明系列故事——买年货(三维背包)

小明系列故事——买年货 Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 2146 Accepted Submission(s): 953 Problem Description春节将至&#xff0c;小明要去超市购置年货&#xff0c;于是小明去了自己经常去…

css 横线_atom.css正式发布,从此跟CSS框架说拜拜。

atom.css 大家好&#xff0c;我写了一个css库atom.css&#xff0c;蛮好用的&#xff0c;所以忍不住分享给大家。(https://github.com/MatrixAge/atom.css)起因写HTML几年了&#xff0c;再到如今的JSX&#xff0c;最大的感受不是枯燥&#xff0c;而是眼花。写样式的时候&#xf…

halcon模板匹配学习(一) Matching 初印象

什么是模板匹配呢&#xff1f;简单而言&#xff0c;就是在图像中寻找目标图像&#xff08;模板&#xff09;&#xff0c;或者说&#xff0c;就是在图像中寻找与模板图像相似部分的一种图像处理技术。依赖于选择的方法不同&#xff0c;模板匹配可以处理各种情形下的变换&#xf…

第五章 面向方面编程___AOP入门

上一篇讲了 AOP 和 OOP 的区别&#xff0c;这一次我们开始入门 AOP 。实现面向方面编程的技术&#xff0c;主要分为两大类&#xff1a; 一是 采用动态代理技术&#xff0c;利用截取消息的方式&#xff0c;对该消息进行装饰&#xff0c;以取代原有对象行为的执行&#xff1b; 二…

java将xml中的标签名称转为小写_深入学习Java Web(七): JSTL标签库

本文转自与博客园一杯凉茶的博客.在之前我们学过在JSP页面上为了不使用脚本&#xff0c;所以我们有了JSP内置的行为、行为只能提供一小部分的功能&#xff0c;大多数的时候还是会用java脚本&#xff0c;接着就使用了EL表达式&#xff0c;基本上EL表达式看似能满足我们的要求&am…

python中*args和**args的不同

上一段代码&#xff0c;大家感受一下 def test_param(*args): print(args) def test_param2(**args): print(args) test_param(test1,test2) >>>(test1,test2) test_param2(p1test1,p2test2) >>>{p1:test1, p2:test2} python提供了两种特别的方法来定义函数的…

halcon模板匹配学习(二) 准备模板

如下&#xff0c;我们将介绍匹配的第一个操作&#xff1a;准备模板 初始时刻&#xff0c;我们准备好参考图像&#xff0c;并对其做一定的处理&#xff0c;然后我们需要从参考图像中导出模板&#xff0c;也就是将参考图像裁剪成所谓的模板图像。获取模板图像可以通过设置ROI来完…

揭秘继承技术之虚函数

虚函数 调用虚函数时函数行为将根据对象所属类的不同而变化。 父类指针或引用指向子类对象时&#xff0c;可访问子类重写方法&#xff08; virtual函数&#xff09;但无法访问在父类中没有定义的子类方法和数据成员。 #include <iostream>using namespace std;class Supe…

java中GET方式提交和POST方式提交

java中GET方式提交的示例&#xff1a; /*** 获取关注列表;* return*/SuppressWarnings("unchecked")public static ArrayList<String> getUserList() {StringBuffer bufferRes new StringBuffer();ArrayList<String> users null;try {URL realUrl new…

基于HALCON的模板匹配方法总结

很早就想总结一下前段时间学习HALCON的心得&#xff0c;但由于其他的事情总是抽不出时间。去年有过一段时间的集中学习&#xff0c;做了许多的练习和实验&#xff0c;并对基于HDevelop的形状匹配算法的参数优化进行了研究&#xff0c;写了一篇《基于HDevelop的形状匹配算法参数…

js 数组移除_2020前端面试--常见的js面试题

&#xff08;答案持续更新...&#xff09; 1.简述同步和异步的区别js是一门单线程语言&#xff0c;所谓"单线程"&#xff0c;就是指一次只能完成一件任务。如果有多个任务&#xff0c;就必须排队&#xff0c;前面一个任务完成&#xff0c;再执行后面一个任务&#xf…

spring-自动加载配置文件\使用属性文件注入

在上一篇jsf环境搭建的基础上 , 加入spring框架 , 先看下目录结构 src/main/resources 这个source folder 放置web项目所需的主要配置,打包时,会自动打包到WEB-INF下 首先看下pom.xml,需要引入一些依赖项: 1 <project xmlns"http://maven.apache.org/POM/4.0.0" x…

pygame碰撞检测

最近在学Pygame,花一段时间做了一个异常简陋版的"打砖块". 这次重点说一下困扰我比较长时间的碰撞检测(个人太菜..). 按照网上教程比较普遍的方法(也可能是我没看见别的),碰撞检测依次计算移动物体与被碰撞物体各个边之间坐标是否相交.例如下列代码,检测小球与窗口的…