python ctypes 一瞥

2015-03-04 Mithrilwoodrat 更多博文 » 博客 » GitHub »

原文链接 http://woodrat.xyz/2015/03/04/ctypes-hello-world/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


ctypes是一个Python库,可以提供C中的数据类型,调用链接库中的函数.

1.加载动态链接库

使用cdll.LoadLibrary或者CDLL.

ex CDLL("libc,so,6")

2.调用已加载库中的函数

下面给出一个调用printf的例子.

Linux中使用ctypes调用libc中的printf打印hello world的代码如下

from ctypes import *

libc = CDLL("libc.so.6") message_str = "Hello world\n" libc.printf("%s",message_str) libc.exit(0)

3 基础数据类型

c_bool 接受任何对象, 如 c_bool 将返回 c_bool(True)

其中一些类型是可以修改的

i =c_int(), i可以被修改

同时有一些类型的数据不能被修改,如指针对象,c_char_p{.reference.internal},c_wchar_p{.reference.internal}, andc_void_p{.reference.internal}.因为改变的将是指针而非内存中的数据.(Python 中 str 对象也是不可修改的)

声明字符数组的函数为 create_string_buffer

s = create_string_buffer("Hello") print sizeof(s),repr(s.raw),s.value >>>6 'Hello\x00' Hello

4 函数注意事项

printf 输出到python standard output channel,而非 sys.stdout.

libc.printf("Hello\n") Hello Out: 6 #stdout 为6 字符串的长度,printf的返回值

Python中的类型,除了integers, strings, 和unicode strings都必须转换为C的格式.

libc.printf("%f\n",45.2)

ArgumentError Traceback (most recent call last) <ipython-input-14-044fe574473e> in <module>() ----> 1 libc.printf("%f\n",45.2)

ArgumentError: argument 2: <type 'exceptions.TypeError'>: Don't know how to convert parameter 2

下面才是正确的写法

In [15]: libc.printf("%f\n",c_double(45.2)) 45.200000 Out[15]: 10

  1. 结构体和联合体

Python中使用结构体和联合体,必须继承ctypes中的Structure或Union类,并且定义_fields_属性._fields_必须为名字和内型的元组构成的列表.

类型必须为ctypes中的

>>>class Point(Structure):fields = [("x",c_int),("y",c_int)] >>>point = Point(1,2) >>>point.x,point.y >>> (1, 2)