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

2019-04-08  本文已影响0人  4thirteen2one
ctypes 类型 C 类型 Python 数据类型
c_bool _Bool bool (1)
c_char char 单字符字节对象
c_wchar wchar_t 单字符字符串
c_byte char int
c_ubyte unsigned char int
c_short short int
c_ushort unsigned short int
c_int int int
c_uint unsigned int int
c_long long int
c_ulong unsigned long int
c_longlong __int64long long int
c_ulonglong unsigned __int64unsigned long long int
c_size_t size_t int
c_ssize_t ssize_tPy_ssize_t int
c_float float float
c_double double float
c_longdouble long double float
c_char_p char * (NUL terminated) 字节串对象或 None
c_wchar_p wchar_t * (NUL terminated) 字符串或 None
c_void_p void * int 或 None

Python程序中导入ctypes模块,载入动态链接库。动态链接库有三种:cdll以及windows下的windll和oledll

使用 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不支持该编码,所以需要转码。

整理出来三种改写方法可以解决这一问题:

  1. 转为byte类型 在字符串前面加b
    from ctypes import *
    msvcrt = cdll.msvcrt
    str = b"Huanhuan!"
    msvcrt.printf(b"Hello %s\n", str)
    
  2. 使用wprintf宽字符显示
    from ctypes import *
    msvcrt = cdll.msvcrt
    str = "Huanhuan!"
    msvcrt.wprintf("Hello %s\n", str)
    
  3. 转码为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有什么区别

上一篇下一篇

猜你喜欢

热点阅读