现在的位置: 首页 > 综合 > 正文

Python调用ctypes使用C函数printf

2013年04月13日 ⁄ 综合 ⁄ 共 1393字 ⁄ 字号 评论关闭

    在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?
    给我出去站着去!

    我乐意!

From: http://blog.sina.com.cn/s/blog_4a94a0db010136oj.html

抱歉!评论已关闭.