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)