菜鸟级别的Python扩展C的实现
2017-03-07 21:42
781 查看
关于Python扩展C有很多大牛写的博客很是齐全,我就从0基础那是假的,有一点点基础,开始整合一下Python调用C的动态链接库的实现。开发基于windows 环境,Python2.7,C编译用的VS2015。
关于Python扩展C有很多的方法,采用调用动态链接库是我觉得比较简单和有效的方法。这方面知识的介绍下面的文章介绍的十分详细哈:
http://baidutech.blog.51cto.com/4114344/743673/
http://www.isnowfy.com/introduction-to-python-c-extension/%20%20%E5%90%84%E7%A7%8DPython%E6%89%A9%E5%B1%95C/C++%E6%96%B9%E6%B3%95)
一开始明确自己的意图,根据自己的需求和使用的方法选择一种方式。本人尝试了API形式的C扩展,但是由于对Python底层的实现不是很了解,止步于结构体的参数传递,为了解决这个问题到了动态链接库的实现。
相对于API方法来讲,dll的实现相对简单的多了,我们只需要把Python中计算量大的方法用C实现,然后再VS中编译成dll文件,然后使用ctypes方法就行了。具体的关于动态链接库的实现见下面的链接:
http://m.blog.csdn.net/article/details?id=52550332
注意,我们是用c写的代码,所以不用加 extern “C”语句,C++的话需要加改语句。CalList 函数的功能是计算结构体数组中∑si=0c[i]∗m[i]T之和的,所以返回的是个浮点型。这个功能并不重要,重要的是CalList的参数是一个结构体数组和一个整形,返回类型是个浮点型。这个函数充分能反应今天要解决的结构体和结构体数组的问题。
解决方法如下:
1.使用ctypes方法,在Python代码中生成一个如C中的结构体:
注意,c_int *20 的意思是该参数是一个长度为20的整形数组。该结构体要和c代码中的结构体对应起来
2. 生成一个大小为len的结构体数组:
并对该结构体数组赋值,具体操作就不赘述了。
3.引入对应的C源码的dll文件:
为了方便,可以把动态链接库文件拷贝到Python工程对应的目录下,方便操作
4.对返回类型进行确认
5.调用动态链接库中的功能函数
酱酱,大功告成咯
看起来干货没多少,可是折腾了2天呢。记录一下,具体的各种扩展方法之间的区别和速度,有很多牛人做了总结,多看,就能避免走弯路了,话说折腾这么久就是因为走了弯路呢。
关于Python扩展C有很多的方法,采用调用动态链接库是我觉得比较简单和有效的方法。这方面知识的介绍下面的文章介绍的十分详细哈:
http://baidutech.blog.51cto.com/4114344/743673/
http://www.isnowfy.com/introduction-to-python-c-extension/%20%20%E5%90%84%E7%A7%8DPython%E6%89%A9%E5%B1%95C/C++%E6%96%B9%E6%B3%95)
一开始明确自己的意图,根据自己的需求和使用的方法选择一种方式。本人尝试了API形式的C扩展,但是由于对Python底层的实现不是很了解,止步于结构体的参数传递,为了解决这个问题到了动态链接库的实现。
相对于API方法来讲,dll的实现相对简单的多了,我们只需要把Python中计算量大的方法用C实现,然后再VS中编译成dll文件,然后使用ctypes方法就行了。具体的关于动态链接库的实现见下面的链接:
http://m.blog.csdn.net/article/details?id=52550332
结构体类型和结构体数组类型的传递
实例代码C源码:#define Tskstu struct Taskstu struct Taskstu { int s; int c[20]; int m[20]; int T; }; ____declspec(dllexport) float CalList(Tskstu * iTsets,int len)
注意,我们是用c写的代码,所以不用加 extern “C”语句,C++的话需要加改语句。CalList 函数的功能是计算结构体数组中∑si=0c[i]∗m[i]T之和的,所以返回的是个浮点型。这个功能并不重要,重要的是CalList的参数是一个结构体数组和一个整形,返回类型是个浮点型。这个函数充分能反应今天要解决的结构体和结构体数组的问题。
解决方法如下:
1.使用ctypes方法,在Python代码中生成一个如C中的结构体:
from ctypes import * import time class CrandStruct(Structure): _fields_=[('si',c_int), ('ci',c_int *20), ('mi', c_int * 20), ('ti', c_int) ]
注意,c_int *20 的意思是该参数是一个长度为20的整形数组。该结构体要和c代码中的结构体对应起来
2. 生成一个大小为len的结构体数组:
StrctSet=(CrandStruct * len)()
并对该结构体数组赋值,具体操作就不赘述了。
3.引入对应的C源码的dll文件:
dllpath="D:\\dllgenerate\\Debug\\dllgenerate.dll" libc=cdll.LoadLibrary(dllpath)
为了方便,可以把动态链接库文件拷贝到Python工程对应的目录下,方便操作
4.对返回类型进行确认
libc.CalList.restype=c_float
5.调用动态链接库中的功能函数
U=libc.CalList(byref(StrctSet),len)
酱酱,大功告成咯
看起来干货没多少,可是折腾了2天呢。记录一下,具体的各种扩展方法之间的区别和速度,有很多牛人做了总结,多看,就能避免走弯路了,话说折腾这么久就是因为走了弯路呢。
相关文章推荐
- 菜鸟学Python(6):在Linux下用C扩展Python要注意的一个问题
- 为Python创建扩展,使python能实现内存共享
- 【Python笔记】如何用C语言实现Python第三方扩展包
- 运维自动化之Python 实现自动配置raid 级别
- 用C语言实现python的扩展模块
- 使用SWIG实现C++扩展Python
- windows 下 使用codeblocks 实现C语言对python的扩展
- Python selenium的js扩展实现
- python扩展实现方法--python与c混和编程
- 扩展Log4j级别,实现邮件提醒
- Ganglia 扩展之Python实现方法
- Trie原理、扩展及Python实现
- 使用swig实现C++的python扩展功能
- python扩展实现方法--python与c混和编程(转)
- Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)
- 为Python创建扩展,使python能实现内存共享
- 用C语言实现python的扩展模块
- Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(爱之初体验)
- 使用vs2008实现C语言对Python2的扩展
- 使用Visual Studio,几步实现Python C++扩展,以及DLL调用