Python中的Ctypes
ctypes是Python中的一个标准库,它提供了一种Python调用C语言动态连接库的方法,可以将C语言的库文件方便的加上一个pyhton的调用接口。
指定连接库文件
在不同平台上ctypes导入的文件是不同的,一般linux上是cdll
,windows上是windll
和oledll
。
cdll
的导入方式用的是cdecl
的调用方式,而windll
的调用方式是stdcall
,oledall
用的也是stdcall
,不过它的前提是函数会返回windows格式的HRESULT
的错误码。
下面是导入windows标准库msvcrt
的一个实现:
from ctypes import *
print(windll.kernel32)
>> ....
print(cdll.msvcrt)
>> ....
libc = cdll.msvcrt
在linux上,导入库的时候需要指定文件名和文件后缀,并且不支持通过属性的方式加载库,一般需要通过cdll.LoadLibrary
或者CDLL
的方式导入。
cdll.LoadLibrary("libc.so.6")
# or
libc = CDLL("libc.so.6")
调用库中的函数
在加载完库之后,库中的函数就可以像一般的属性去访问。
from ctypes import *
libc.printf
>> <_FuncPtr....
libc.time(None)
>>> 115....
需要注意的是stdcall
和cdecl
的调用是有区别的,如果用cdecl
的方式调用一个stdcall
的函数会触发一个ValueError
的错误,反之亦然。
在进行函数调用的时候python会自动去尝试从python类型到c语言类型的转换,如果转换失败就会出现ArgumentError
,比如
printf = libc.printf
# OK, string converted
printf(b"Hello %s", b"world")
printf(b"Hello %s", "world")
# FAIL float not converted
printf(b"price is %f", 42.5)
# OK add conversion
printf(b"price is %f", c_double(42.5))
如果需要传入一些自定义的类作为参数,可以定义一个_as_parameter_
的方法,这样将类作为参数的时候python会自动进行转换。
数组
为了方便产生数组,ctypes类型重载了操作符*
,因此可以通过下面的方式产生一个指定长度的数组:
from ctypes import *
# 创建一个数组类型
type_int_array_10 = c_int * 10
# 例化创建的数组类型,得到一个数组的实例
my_array = type_int_array_10()
最后更新于 2017-12-04 14:29:28 并被添加「」标签,已有 2116 位童鞋阅读过。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。