创建指针实例
>>> from ctypes import * >>> i = c_int(42) >>> pi = pointer(i) >>> >>> pi.contents c_long(42) >>>使用cast()类型转换
>>> class Bar(Structure): ... _fields_ = [("count", c_int), ("values", POINTER(c_int))] ... >>> bar = Bar() >>> bar.values = (c_int * 3)(1, 2, 3) >>> bar.count = 3 >>> for i in range(bar.count): ... print bar.values[i] ... 1 2 3 >>> >>> bar = Bar() >>> bar.values = cast((c_byte * 4)(), POINTER(c_int)) # 这里转成需要的类型 >>> print bar.values[0] 0 >>>类似于C语言定义函数时,会先定义返回类型,然后具体实现再定义,当遇到下面这种情况时,也需要这么干:
>>> class cell(Structure): ... _fields_ = [("name", c_char_p), ... ("next", POINTER(cell))] ... Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 2, in cell NameError: name 'cell' is not defined >>> # 不能调用自己,所以得像下面这样 >>> from ctypes import * >>> class cell(Structure): ... pass ... >>> cell._fields_ = [("name", c_char_p), ... ("next", POINTER(cell))] >>> 调用.so/.dll可以简单地将"so"和"dll"理解成Linux和windows上动态链接库的指代,这里我们以Linux为例。注意,ctypes提供的接口会在不同系统上有出入,比如为了加载动态链接库, 在Linux上提供的是 cdll, 而在Windows上提供的是 windll 和 oledll 。
加载动态链接库 from ctypes import * >>> cdll.LoadLibrary("libc.so.6") <CDLL 'libc.so.6', handle ... at ...> >>> libc = CDLL("libc.so.6") >>> libc <CDLL 'libc.so.6', handle ... at ...> >>> 调用加载的函数 >>> print libc.time(None) 1150640792 >>> print hex(windll.kernel32.GetModuleHandleA(None)) 0x1d000000 >>> 设置个性化参数ctypes会寻找 _as_paramter_ 属性来用作调用函数的参数传入,这样就可以传入自己定义的类作为参数,示例如下:
>>> class Bottles(object): ... def __init__(self, number): ... self._as_parameter_ = number ... >>> bottles = Bottles(42) >>> printf("%d bottles of beer\n", bottles) 42 bottles of beer 19 >>> 指定函数需要参数类型和返回类型