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实现遍历windows所有窗口并输出窗口标题的方法
Mar 13 Python
Python制作爬虫抓取美女图
Jan 20 Python
如何在sae中设置django,让sae的工作环境跟本地python环境一致
Nov 21 Python
PyQt5笔记之弹出窗口大全
Jun 20 Python
在django中,关于session的通用设置方法
Aug 06 Python
python爬虫豆瓣网的模拟登录实现
Aug 21 Python
Pycharm+django2.2+python3.6+MySQL实现简单的考试报名系统
Sep 05 Python
使用 tf.nn.dynamic_rnn 展开时间维度方式
Jan 21 Python
TensorFlow实现保存训练模型为pd文件并恢复
Feb 06 Python
python Xpath语法的使用
Nov 26 Python
浅析pandas随机排列与随机抽样
Jan 22 Python
python多次执行绘制条形图
Apr 20 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数字运算验证码的实现代码
2015/07/30 PHP
php实现的SSO单点登录系统接入功能示例分析
2016/10/12 PHP
yii2中LinkPager增加总页数和总记录数的实例
2017/08/28 PHP
Laravel如何实现适合Api的异常处理响应格式
2020/06/14 PHP
通过Javascript创建一个选择文件的对话框代码
2012/06/16 Javascript
你必须知道的Javascript知识点之&quot;单线程事件驱动&quot;的使用
2013/04/23 Javascript
jQuery实现渐变下拉菜单的简单方法
2015/03/11 Javascript
javascript中window.open在原来的窗口中打开新的窗口(不同名)
2015/11/15 Javascript
javascript中eval和with用法实例总结
2015/11/30 Javascript
详解AngularJS过滤器的使用
2016/03/11 Javascript
javascript基础知识
2016/06/07 Javascript
js改变css样式的三种方法推荐
2016/06/28 Javascript
微信小程序 ecshop地址三级联动实现实例代码
2017/02/28 Javascript
jquery请求servlet实现ajax异步请求的示例
2017/06/03 jQuery
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
JS 中document.write()的用法和清空的原因浅析
2017/12/04 Javascript
webpack 3.X学习之多页面打包的方法
2018/09/04 Javascript
详解vue 兼容IE报错解决方案
2018/12/29 Javascript
vue项目创建步骤及路由router
2020/01/14 Javascript
js实现星星海特效的示例
2020/09/28 Javascript
采用python实现简单QQ单用户机器人的方法
2014/07/03 Python
Python中atexit模块的基本使用示例
2015/07/08 Python
Python中super()函数简介及用法分享
2016/07/11 Python
python3.8与pyinstaller冲突问题的快速解决方法
2020/01/16 Python
python和opencv构建运动检测器的实现
2021/03/03 Python
css3实现超立体3D图片侧翻倾斜效果
2014/04/16 HTML / CSS
Ellos丹麦:时尚和服装在线
2016/09/19 全球购物
Solaris操作系统的线程机制
2012/12/23 面试题
应用化学专业职业生涯规划书
2014/01/22 职场文书
《恐龙》教学反思
2014/04/27 职场文书
教师敬业奉献模范事迹材料
2014/05/18 职场文书
六一儿童节演讲稿
2014/05/23 职场文书
六查六看自查报告
2014/10/14 职场文书
2014年企业党建工作总结
2014/12/18 职场文书
干货分享:推荐信写作技巧!
2019/06/21 职场文书
详解flex:1什么意思
2022/07/23 HTML / CSS