python使用ctypes调用扩展模块的实例方法


Posted in Python onJanuary 28, 2020

楔子

我们知道python的执行效率不是很高,而且由于GIL的原因,导致python不能充分利用多核CPU。一般的解决方式是使用多进程,但是多进程开销比较大,而且进程之间的通信也会比较麻烦。因此在解决效率问题上,我们会把那些比较耗时的模块使用C或者C++编写,然后编译成动态链接库,Windows上面是dll,linux上面则是so,编译好之后,交给python去调用。而且通过扩展模块的方式还可以解决python的GIL的问题,因此如果想要利用多核,我们仍然可以通过扩展模块的方式。

python如何调用扩展模块

python调用扩展模块的一种比较简单的方式就是使用ctypes这个库,这个库是python官方提供的,任何一个版本的python都可以使用,我们通过ctypes可以很轻松地调用扩展模块。

演示

#include <stdio.h>

void test()
{
  printf("hello world\n");
}

我们定义了一个很简单的函数,下面我们就可以将其编译成扩展模块了。在Windows是dll,linux上是so,编译的命令是一样的。我这里以Windows 为例,记得在Windows上要安装MinGW,或者安装VsCode,我这里使用的是MinGW,因为VsCode太大了。

gcc -o dll文件或者so文件 -shared c或者c++源文件

我这里的C源文件叫做1.c,我们编译成mmp.dll吧,所以命令就可以这么写:gcc -o mmp.dll -shared 1.c

python使用ctypes调用扩展模块的实例方法

下面就可以使用python去调用了。

import ctypes

# 使用ctypes很简单,直接import进来,然后使用ctypes.CDLL这个类来加载动态模块
# 如果在Windows上还可以使用ctypes.WinDLL。
# 因为看ctypes源码的话,会发现WinDLL也是一个类并且继承自CDLL
# 所以在linux上使用ctypes.CDLL,
# 而在Windows上既可以使用WinDLL、也可以使用CDLL加载动态模块
lib = ctypes.CDLL("./mmp.dll") # 加载之后就得到了扩展模块
# 我们可以直接通过.的方式去调用里面的函数了,会发现成功打印
lib.test() # hello world

# 但是为了确定是否存在这个函数,我们一般会使用反射去获取
# 因为如果函数不存在通过.的方式调用会抛异常的
func = getattr(lib, "test", None)
if func:
  print(func) # <_FuncPtr object at 0x0000029F75F315F0>
  func() # hello world


# 不存在test_xx这个函数,所以得到的结果为None
func1 = getattr(lib, "test_xx", None)
print(func1) # None

所以使用ctypes去调用扩展模块非常方便

1.通过ctypes.CDLL("dll或者so的路径"),如果是Windows还可以使用ctypes.WinDLL("dll路径")。另外这两种加载方式分别等价于:ctypes.CDLL("dll或者so的路径") == ctypes.cdll.LoadLibrary("dll或者so的路径"),ctypes.WinDLL("dll路径") == ctypes.windll.LoadLibrary("dll路径")。但是注意的是:linux上只能使用ctypes.CDLL和ctypes.cdll.LoadLibrary,而Windows上ctypes.CDLL、ctypes.cdll.LoadLibrary、ctypes.WinDLL、ctypes.windll.LoadLibrary都可以使用。但是一般我们都使用ctypes.CDLL即可,另外注意的是:dll或者so文件的路径最好是绝对路径,即便不是也要表明层级,比如我们这里的py文件和dll文件是在同一个目录下,但是我们加载的时候不可以写mmp.dll,这样会报错找不到,要写成./mmp.dll。

2.加载动态模块之后会返回一个对象,我们上面起名为lib,这个lib就是得到的扩展模块了。

3.然后可以直接通过lib调用里面的函数,但是一般我们会使用反射的方式来获取,因为不知道函数到底存不存在,如果不存在直接调用会抛出异常,如果存在这个函数我们才会执行。

以上就是本次介绍的全部相关知识点,如果大家有任何补充的地方可以联系三水点靠木小编。

Python 相关文章推荐
python插入排序算法的实现代码
Nov 21 Python
Python多进程同步Lock、Semaphore、Event实例
Nov 21 Python
Python实现建立SSH连接的方法
Jun 03 Python
Python实现SMTP发送邮件详细教程
Mar 02 Python
python中实现将多个print输出合成一个数组
Apr 19 Python
python smtplib模块自动收发邮件功能(一)
May 22 Python
Python3实现二叉树的最大深度
Sep 30 Python
opencv python图像梯度实例详解
Feb 04 Python
Python调用C语言程序方法解析
Jul 07 Python
详解pytorch tensor和ndarray转换相关总结
Sep 03 Python
Python打包exe时各种异常处理方案总结
May 18 Python
Python实现双向链表基本操作
May 25 Python
Python 时间戳之获取整点凌晨时间戳的操作方法
Jan 28 #Python
使用Python制作新型冠状病毒实时疫情图
Jan 28 #Python
代码总结Python2 和 Python3 字符串的区别
Jan 28 #Python
使用Python爬虫库BeautifulSoup遍历文档树并对标签进行操作详解
Jan 25 #Python
Python爬虫库BeautifulSoup获取对象(标签)名,属性,内容,注释
Jan 25 #Python
Python爬虫库BeautifulSoup的介绍与简单使用实例
Jan 25 #Python
使用Python爬虫库requests发送表单数据和JSON数据
Jan 25 #Python
You might like
学习php开源项目的源码指南
2014/12/21 PHP
codeigniter显示所有脚本执行时间的方法
2015/03/21 PHP
PHP格式化MYSQL返回float类型的方法
2016/03/30 PHP
thinkPHP简单实现多个子查询语句的方法
2016/12/05 PHP
php PDO判断连接是否可用的实现方法
2017/04/03 PHP
极酷的javascirpt,让你随意编辑任何网页
2007/02/25 Javascript
jQuery EasyUI NumberBox(数字框)的用法
2010/07/08 Javascript
jQuery插件开发基础简单介绍
2013/01/07 Javascript
jquery实现手风琴效果实例代码
2013/11/15 Javascript
Vue.js 2.0窥探之Virtual DOM到底是什么?
2017/02/10 Javascript
JQuery选中select组件被选中的值方法
2018/03/08 jQuery
AngularJS与BootStrap模仿百度分页的示例代码
2018/05/23 Javascript
三分钟学会用ES7中的Async/Await进行异步编程
2018/06/14 Javascript
vue组件之间数据传递的方法实例分析
2019/02/12 Javascript
微信小程序 image组件遇到的问题
2019/05/28 Javascript
layui对工具条进行选择性的显示方法
2019/09/19 Javascript
详解小程序云开发攻略(解决最棘手的问题)
2019/09/30 Javascript
解决在Vue中使用axios用form表单出现的问题
2019/10/30 Javascript
[01:16:50]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第一场 3月7日
2021/03/11 DOTA
python实现系统状态监测和故障转移实例方法
2013/11/18 Python
彻底理解Python list切片原理
2017/10/27 Python
Python3.遍历某文件夹提取特定文件名的实例
2018/04/26 Python
详解使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件
2019/08/23 Python
python实现的Iou与Giou代码
2020/01/18 Python
使用Keras中的ImageDataGenerator进行批次读图方式
2020/06/17 Python
详解基于python的图像Gabor变换及特征提取
2020/10/26 Python
Kathmandu美国网站:新西兰户外运动品牌
2019/03/23 全球购物
大三预备党员入党思想汇报
2014/01/08 职场文书
房地产财务管理制度
2014/02/02 职场文书
争先创优演讲稿
2014/09/15 职场文书
公安机关党的群众路线教育实践活动剖析材料
2014/10/10 职场文书
先进典型事迹材料
2014/12/29 职场文书
卢旺达饭店观后感
2015/06/05 职场文书
小组组名及励志口号
2015/12/24 职场文书
Java并发编程之详解CyclicBarrier线程同步
2021/06/23 Java/Android
SpringMVC 整合SSM框架详解
2021/08/30 Java/Android