Python调用ctypes使用C函数printf的方法


Posted in Python onAugust 23, 2017

在Python程序中导入ctypes模块,载入动态链接库。动态链接库有三种:cdll以及windows下的windll和oledll,cdll载入导出函数使用标准的cdecl调用规范的库,而windll载入导出函数符合stdcall调用规范(Win32 API的原生约定)的库,oledll也使用stdcall调用规范,并假设函数返回Windows的HRESULT错误代码。错误代码用于在出错时自动抛出WindowsError这个Python异常,可以使用COM函数得到具体的错误信息。

使用cdll.msvcrt即可调用MS标准的C库msvcrt,msvcrt包含了大部分标准C函数。

下面来看一下简单的printf函数。

from ctypes import *
msvcrt = cdll.msvcrt
str = "Huanhuan!"
msvcrt.printf("Hello %s\n", str)

这样就可以使用C语言中的printf函数进行输出。
如果在IDLE里运行的话会发现程序没有任何输出结果,这是因为printf是打印到真实的标准输出,而不是sys.stdout。如果想要看到运行结果,可以在CMD里运行python test.py来查看结果,前提是已经设置好了Python的环境变量。或者有一个曲线方法可以在IDLE中显示输出结果,请曲线阅读到文章最后。

如果使用的是Py3K,在控制台里会看到只有开头字符H被输出了。因为Py3K使用的是Unicode编码,而printf不支持该编码,所以需要转码。整理出来三种改写方法可以解决这一问题。

# A 转为byte类型 在字符串前面加b
from ctypes import *
msvcrt = cdll.msvcrt
str = b"Huanhuan!"
msvcrt.printf(b"Hello %s\n", str)

# B 使用wprintf宽字符显示
from ctypes import *
msvcrt = cdll.msvcrt
str = "Huanhuan!"
msvcrt.wprintf("Hello %s\n", str)

# C 转码为utf-8
from ctypes import *
msvcrt = cdll.msvcrt
str = "Huanhuan!"
result = "Hello " + str + "\n"
result = result.encode("utf-8")
msvcrt.printf(result)

最后来搞定在IDLE中曲线显示输出结果的方法。

from ctypes import *
msvcrt = cdll.msvcrt
str = b"Huanhuan!"
s = create_string_buffer(100)  # 必须足够长
msvcrt.sprintf(s, b'Hello %s\n', str)
print(s.value.decode('utf-8'))

先使用sprintf函数把结果输出到s变量,然后再用Python自带的print方法输出s的value。

好了,通过以上的各种方法就可以解决Py3K调用C函数printf的问题了。

什么?你问我为什么费这么大劲非要用printf输出,而不是直接用Python自带的print?

python的print和c的printf有什么区别

print([object, ...], *, sep=' ', end='\n', file=sys.stdout, flush=False)

输出对象到流文件,sep指定分割符,end指定结束符。参数转换为字符串写入输出流,如果没有输出内容直接输出end结束符。file参数必须是包含write方法的对象,默认输出到标准输出。

int printf( char * format, ... );

根据参数 format 字符串来转换并格式化数据,然后将结果输出到标准输出设备(显示器),直到出现字符串结束('\0')为止。
参数 format 字符串可包含下列三种字符类型:

一般文本,将会直接输出
ASCII 控制字符,如\t、\n 等有特定含义
格式转换字符

格式转换为一个百分比符号(%)及其后的格式字符所组成。一般而言,每个%符号在其后都必需有一个参数与之相呼应(只有当%%转换字符出现时会直接输出%字符),而欲输出的数据类型必须与其相对应的转换字符类型相同。

Python 相关文章推荐
Python批量修改文件后缀的方法
Jan 26 Python
Python 列表list使用介绍
Nov 30 Python
Python中的深拷贝和浅拷贝详解
Jun 03 Python
Java分治归并排序算法实例详解
Dec 12 Python
Python 爬虫之Beautiful Soup模块使用指南
Jul 05 Python
python实现多人聊天室
Mar 31 Python
Django 创建/删除用户的示例代码
Jul 24 Python
Python发送邮件的实例代码讲解
Oct 16 Python
python 使用建议与技巧分享(四)
Aug 18 Python
使用Python Tkinter实现剪刀石头布小游戏功能
Oct 23 Python
python控制台打印log输出重复的解决方法
May 14 Python
python神经网络Xception模型
May 06 Python
使用Python实现博客上进行自动翻页
Aug 23 #Python
Python模拟鼠标点击实现方法(将通过实例自动化模拟在360浏览器中自动搜索python)
Aug 23 #Python
Python PyQt5标准对话框用法示例
Aug 23 #Python
Python PyQt5实现的简易计算器功能示例
Aug 23 #Python
Python实现的密码强度检测器示例
Aug 23 #Python
python+selenium+autoit实现文件上传功能
Aug 23 #Python
Django与JS交互的示例代码
Aug 23 #Python
You might like
PHP7正式版测试,性能惊艳!
2015/12/08 PHP
Smarty日期时间操作方法示例
2016/11/15 PHP
php使用PDO下exec()函数查询执行后受影响行数的方法
2017/03/28 PHP
PHP实现提高SESSION响应速度的几种方法详解
2019/08/09 PHP
javascript中的有名函数和无名函数
2007/10/17 Javascript
jQuery checkbox全选/取消全选实现代码
2009/11/14 Javascript
收集的一些Array及String原型对象的扩展实现代码
2010/12/05 Javascript
AngularJS基础 ng-keydown 指令简单示例
2016/08/02 Javascript
jQuery 获取页面li数组并删除不在数组中的key
2016/08/02 Javascript
JS获取及验证开始结束日期的方法
2016/08/20 Javascript
AngularJS 霸道的过滤器小结
2017/04/26 Javascript
微信小程序页面开发注意事项整理
2017/05/18 Javascript
浅谈Angular路由复用策略
2017/10/04 Javascript
vue2.0 兄弟组件(平级)通讯的实现代码
2018/01/15 Javascript
Taro集成Redux快速上手的方法示例
2018/06/21 Javascript
React-router4路由监听的实现
2018/08/07 Javascript
Vue的watch和computed方法的使用及区别介绍
2018/09/06 Javascript
vue动态绑定class选中当前列表变色的方法示例
2018/12/19 Javascript
基于vue 动态菜单 刷新空白问题的解决
2020/08/06 Javascript
从头学Python之编写可执行的.py文件
2017/11/28 Python
python实现决策树ID3算法的示例代码
2018/05/30 Python
Python Requests库基本用法示例
2018/08/20 Python
浅析Python与Mongodb数据库之间的操作方法
2019/07/01 Python
python django 原生sql 获取数据的例子
2019/08/14 Python
pandas read_excel()和to_excel()函数解析
2019/09/19 Python
python 解决print数组/矩阵无法完整输出的问题
2020/02/19 Python
Django中ORM找出内容不为空的数据实例
2020/05/20 Python
python mock测试的示例
2020/10/19 Python
python 制作磁力搜索工具
2021/03/04 Python
世界最大的海报和艺术印刷商店:AllPosters.com
2017/02/01 全球购物
澳大利亚购买健身器材网站:Gym Direct
2019/12/19 全球购物
企业法律事务工作总结
2015/08/11 职场文书
2019中小学生安全过暑期倡议书
2019/06/24 职场文书
JavaScript offset实现鼠标坐标获取和窗口内模块拖动
2021/05/30 Javascript
React forwardRef的使用方法及注意点
2021/06/13 Javascript
SpringBoot实现异步事件驱动的方法
2021/06/28 Java/Android