python ctypes 一瞥
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
- 结构体和联合体
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)