2019独角兽企业重金招聘Python工程师标准>>>

原文地址:[http://www.isnowfy.com/introduction-to-python-c-extension/]

python是一门非常方便的动态语言,很多你用c或者java要很多行的代码,可能python几行就搞定了,所以python社区一直有个口号 “人生苦短,我用python”,但是方便至于,也带来速度上的问题。python最被人诟病的就是程序的运行速度了,所以结合c的快速和python的 方便,就诞生了很多解决方案。首先注意到python就是c写成的,所以最根本的解决方案就是利用原生的python c api来写c程序,然后编译成链接库文件(linux下就是so文件),然后在python中直接调用,而且其他的解决方案也基本是围绕这个思路,只不过 替你做了很多重复的工作。这次主要是简要介绍下python c api,swig,sip,ctypes,cython,cffi的使用。

python c api

首先来看最原始的就是使用python c api了。

  1. #include <Python.h>

  2. static PyObject* add(PyObject* self, PyObject* args){

  3. int a = 0;

  4. int b = 0;

  5. if(!PyArg_ParseTuple(args, "i|i", &a, &b))

  6. return NULL;

  7. return Py_BuildValue("i", a+b);

  8. }

  9. static PyObject* sub(PyObject* self, PyObject* args){

  10. int a = 0;

  11. int b = 0;

  12. if(!PyArg_ParseTuple(args, "i|i", &a, &b))

  13. return NULL;

  14. return Py_BuildValue("i", a-b);

  15. }

  16. static PyMethodDef addMethods[]={

  17. {"add", add, METH_VARARGS},

  18. {"sub", sub, METH_VARARGS},

  19. {NULL, NULL, 0, NULL}

  20. };

  21. void initmytest(){

  22. Py_InitModule("mytest", addMethods);

  23. }

首先是引入Python.h这个头文件,所以编译的时候要注意引入python的库,python中的对象在c中都是用PyObject来表示的, 程序中定义了add和sub两个方法,然后编写init函数,名字注意是init加上你的module的名字,然后调用Py_InitModule函数来 告诉python你定义的函数有哪些。然后就是把他编译成so文件。

  1. gcc mytest.c -shared -lpython2.7 -L /usr/lib/python2.7/ -I /usr/include/python2.7/ -o mytest.so

这样你就可以在python中import mytest这样引用,用法就和用其他python的模块一样了。

swig

首先要说明的是swig可以进行很多语言的调用转换,不止是可以让python调用c。swig和sip都被称作wrapper,就是说他对你的原 有函数进行了包装。看到之前用python c api的方式里,我们必须严格按照python c api的方式来写代码,破坏了原有c程序的可读性,于是wrapper的思想就是把原生c程序包装成python c api那种方式的代码,再去生成so文件。因此我们要做的是首先写c文件。

  1. int add(int a, int b){

  2. return a+b;

  3. }

  4. int sub(int a, int b){

  5. return a-b;

  6. }

然后再去写一个swig格式的接口文件。

  1. %module mytest

  2. %{

  3. extern int add(int a, int b);

  4. extern int sub(int a, int b);

  5. %}

  6. extern int add(int a, int b);

  7. extern int sub(int a, int b);

然后就可以运行swig,他会自动生成python c api写的代码,并且会自动编译出so文件来调用。

sip

来看sip,sip是swig发展而来是方便python调用c的,所以基本使用方式都是差不多,只不过接口文件略有差异。

  1. %Module(name=mytest, language="C")

  2. int add(int a, int b);

  3. int sub(int a, int b);

ctypes

ctypes提供了另外的思路来调用c程序。首先ctypes是python的标准库,所以如果用ctypes你不需要额外的其他的东西。 ctypes让你可以在python直接写代码加载c的链接库so文件来调用,就是说如果你用so文件而没有源文件的话,你仍然可以用ctypes去调 用。

  1. from ctypes import *

  2. f = 'mytest.so'

  3. cdll.LoadLibrary(f)

  4. api = CDLL(f)

  5. api.add.argtypes = [c_int, c_int]

  6. api.add.restype = c_int

  7. api.sub.argtypes = [c_int, c_int]

  8. api.sub.restype = c_int

  9. print api.add(3, 2)

  10. print api.sub(3, 2)

有点像在python中去写接口文件,由于是python的标准库,所以这种方式用的还是蛮多的。

cython

cython的方法呢是利用类似python的语法来写调用c程序的接口,并且可以同时方便的地用c函数和python函数。看代码理解。

  1. int sub(int a, int b){

  2. return a-b;

  3. }

我们可以有一些c写成的代码。

  1. cdef extern from 'test.c':

  2. int sub(int a, int b)

  3. def add(int a, int b):

  4. return a+b

  5. def mysub(a, b):

  6. return sub(a, b)

然后在cython中我们既可以引入c文件调用c文件中的函数,也可以去调用python中的函数,调用cython程序会把他变成纯正的c文件,然后编译成so文件就可以使用了。

from cffi import FFI
ffi = FFI()
ffi.cdef("""
int add(int a, int b);
int sub(int a, int b);
""")
lib = ffi.verify('#include "mytest.c"')
print lib.add(1,2)

最后是cffi,cffi类似于ctypes直接在python程序中调用c程序,但是比ctypes更方便不要求编译成so再调用,注意到上面的 所有方式都是需要去编译成so文件后再在python中调用,而cffi允许你直接调用c文件来使用里面的函数了,为什么这么神奇呢,其实是cffi在解 释过程中才帮你把c编译为so文件的。。。

然后基本就是这样了,最后给我的感觉就是:基本上原生的python c api的写法最麻烦了,但是一些需要高级用法的话还是这个更容易控制;方便一点的就是用wrapper;ctypes好处是,他是python的标准模块 并且不需要另外写其他的额外程序(接口程序之类的);cython好处就是可以方便的同时调用c函数和python函数,并且是类python语法,用起 来很方便;CFFI好处是调用c更加方便,不用编译 so。最后本文只是对各种用法简单的介绍,并没有深入的对各种用法的优缺点进行比较,因此如果想了解更多内容还是去看官方文档吧。。。

转载于:https://my.oschina.net/u/2306127/blog/369996

python的c语言扩展方法简介相关推荐

  1. Python:C语言扩展

    Python:C语言扩展 (2013-05-29 14:38:02) 转载▼ 标签: 杂谈 分类:Python   没有什么比对着书敲的代码仍然出错更令人沮丧了.<Python编程入门经典> ...

  2. 博途中用的是c吗_S7-1500系列博途中使用SCL语言编程方法简介

    S7-1500系列博途中使用SCL语言编程方法简介 SCL:Structured Contorl Language,结构化控制语言. 在TIA博途软件中,默认支持SCL语言,在建立程序块时可以直接选择 ...

  3. python转cython_Cython 0.23 发布 Python 的 C 语言扩展

    Cython 0.23 发布,此版本相比第二个测试版本改进很小,还有一些 bug 修复. 此版本是个重要的特性版本,值得关注的改进如下: * PEP 492 (async/await) 和 PEP 4 ...

  4. S7-1500系列博途中使用SCL语言编程方法简介

    SCL:Structured Contorl Language,结构化控制语言. 在TIA博途软件中,默认支持SCL语言,在建立程序块时可以直接选择SCL语言. SCL语言类似计算机高级语言,如果你有 ...

  5. python代码用c语言封装_使用C语言扩展Python程序的简单入门指引

    一.简介 Python是一门功能强大的高级脚本语言,它的强大不仅表现在其自身的功能上,而且还表现在其良好的可扩展性上,正因如此,Python已经开始受到越来越多人的青睐,并且被屡屡成功地应用于各类大型 ...

  6. c语言实现python语法_用C语言扩展Python的功能

    转自:http://www.ibm.com/developerworks/cn/linux/l-pythc/ 一.简介 Python是一门功能强大的高级脚本语言,它的强大不仅表现在其自身的功能上,而且 ...

  7. 如何将c语言程序封装供python调用_转:用C语言扩展Python的功能

    一.简介 Python是一门功能强大的高级脚本语言,它的强大不仅表现在其自身的功能上,而且还表现在其良好的可扩展性上,正因如此,Python已经开始受到越来越多人的青睐,并且被屡屡成功地应用于各类大型 ...

  8. c语言转换为python语言_【转】用C语言扩展Python的功能

    一.简介 Python是一门功能强大的高级脚本语言,它的强大不仅表现在其自身的功能上,而且还表现在其良好的可扩展性上,正因如此,Python已经开始受到越来越多人的青睐,并且被屡屡成功地应用于各类大型 ...

  9. python怎么调用c语言_Python调用C语言程序方法解析

    Python调用C语言程序方法解析 首先我们需要将编写好的c程序文件编译为动态库文件(后缀名为.so) 使用下面的命令: gcc 原文件名.c -shared -o 新文件名.so 然后在python ...

最新文章

  1. Jekyll博客统计访问量,阅读量工具总结--LeanCloud,不蒜子,Valine,Google Analytics
  2. 耳机是怎么传输声音的_win7电脑耳机有声音外放没声音怎么办
  3. Python机器学习:评价分类结果001准确度和混淆矩阵
  4. soar ddl审核规范_SQL Server审核功能– DDL事件审核示例
  5. 无限火力挤爆服务器,LOL:无限火力出炉,众多云玩家宣布回归!服务器出现爆满情况...
  6. SpringCloud实战(三)集成Open-Feign实现远程⽅法调⽤
  7. MapGIS67二次开发环境搭建
  8. 自媒体时事热点类素材哪里找?推荐这3个网站
  9. oracle恢复几天前的数据,恢复oracle数据到以前的某个时间点
  10. kpw4换壁纸_发挥全部潜能,Kindle越狱指南
  11. 9款主流图表控件轻松实现数据可视化
  12. python单位根检验看结果_时间序列的ADF检验(单位根检验)
  13. 【新手案例】Python3.7如何获取网络时间
  14. 中国银行app,H5页面调取支付,并返回状态码。
  15. linux命令下jq的用法(curl 格式化输出json 字符串)
  16. vue3实现鼠标左键拖拽画矩形框框选功能
  17. 【JMX】1. 什么是JMX、JDK中的JMX实现
  18. 进入网页页面的开发者模式——三种方式
  19. 计算机考研院校对比与分析-南京理工VS华南理工
  20. 慎用一键修改hosts软件

热门文章

  1. raspbian wifi设置
  2. 医疗卫生信息化 医学信息 医院管理 医疗信息化 资源下载
  3. Asp.net上传文件限制,在大于5M的时候出现DNS解析错误,解决方法。
  4. ibm服务器hyper-v搭建的虚拟机操作系统数据如何导出到本机,将虚拟机从Hyper-V转移到KVM|导出完整vhdx磁盘转换qcow2...
  5. java加密文件夹_使用java.util.zip压缩文件夹,支持加密,增加描述
  6. php string pos,有关pos()的文章推荐10篇
  7. linux tomcat6 jmx,Zabbix3.2.6之通过JMX监控Tomcat
  8. seata的部署和集成
  9. Spring-Cloud中的统一配置中心
  10. spring相关API