Python使用ctypes模块调用DLL
注意
使用ctypes调用DLL文件时,要保证python解释器的位数和DLL使用的C解释器位数一致,32位C解释器必须与32位Python解释器配合使用,否则会报错OSError: [WinError xxx] xxx 不是有效的 Win32 应用程序
1 | # 查看当前python环境使用的解释器位数 |
加载
针对DLL的两种调用约定,使用不同的调用方法
1 | import ctypes |
调用DLL内方法
通过lib.methodName
即可调用DLLn内部方法,调用DLL内部方法时,要将python参数通过ctypes转换为C语言参数
ctypes C类型与python类型对应表
ctypes type | C type | Python type |
---|---|---|
c_bool | _Bool | bool(1) |
c_char | char | 单个字符的bytes对象,等同于 b’a’ |
c_wchar | wchar_t | 单个字符的字符串 |
c_byte | char | int |
c_ubyte | unsigned char | int |
c_short | short | int |
c_ushort | unsigned short | int |
c_int | int | int |
c_uint | unsigned int | int |
c_long | long | int |
c_ulong | unsigned long | int |
c_longlong | __int64 or long long | int |
c_size_t | size_t | int |
c_ssize_t | ssize_t | int |
c_float | float | float |
c_double | double | float |
c_longdouble | long double | float |
c_cahr_p | char * | bytes object or None |
c_wchar_p | wchar * | string or None |
c_void_p | void * | int or None |
调用范例
Example1:
1 | # DLL中定义的函数 |
1 | # lib为调用CDLL或WinDLL返回的对象 |
Example2:
1 | # DLL中定义的方法,方法内部会通过buf和data的指针,修改参数值向函数外传值 |
1 | data = ctypes.c_int() |
Note:
C语言字符串的末尾会带有‘\0’结束符, 直接处理字符串时要注意‘\0’
ctypes.byref用来传递引用参数,ctypes.pointer()作为传参会创建实际的指针对象
byref可以通过value属性获取值,pointer可以通过contents获取返回值
如果参数需要传递空指针时,直接传递None,用None作为空指针
Example3:
数组参数的创建
1 | # arr1 = int[5] 并且值为0 |
Example4:
结构体传参, 结构体参数可以通过Python class创建
1 | # _fileds_属性定义为二维tuple |
Note:
python中定义的结构体的class名,变量名可以不同于C中定义的结构体,但是变量的类型和定义顺序一定要与C中的类型顺序一致。