ctypes是Python的一个外部库,提供和C语言兼容的数据类型,可以很方便地调用DLL中输出的C接口函数。
#### 1.加载dll和取出函数
```python
from ctypes import *
dll = cdll.LoadLibrary(dllpath) #dllpath是字符串
dll = windll.LoadLibrary(dllpath)
```
上面两行使用哪一行,取决于导出函数的调用规范(cdecl或stdcall).也可以使用下面两行代替:
```python
dll = CDLL(dllpath) #注意和上面大小写的区别
dll = WinDLL(dllpath)
```
注意,这里使用的dll必须和python平台匹配,比如都是32位的或者都是64位的。因为本质上是一个exe加载一个dll,无法跨平台。
加载dll后,可直接得到dll中的导出函数地址.
```python
func = dll.func_name #func_name 是dll的导出函数
```
有时动态链接库导出c++函数时,并不是有效的Python标识符,例如 "??2@YAPAXI@Z" 。这种情况下,必须使用getattr 获取函数:
```python
func = getattr(cdll.msvcrt,"??2@YAPAXI@Z")
```
在Windows上,有些动态链接库导出函数不是用名字,而是用序号(ordinal)。这时需通过索引获取:
```python
func = cdll.kernel32[1]
```
#### 2.函数参数和返回值
上面只是得到了函数地址,还无法进行函数调用.要进行正确的函数调用,需设置好参数和返回值类型.
ctypes支持的原生数据类型如下:
| ctypes类型 | C 类型 | Python 类型 |
| ------------------ | -------------------------------------- | -----------------------------------|
| c_char | char | 1-character string |
| c_wchar | wchar_t | 1-character unicode string |
| c_byte | char | int/long |
| c_ubyte | unsigned char | int/long |
| c_bool | bool | bool |
| c_short | short | int/long |
| c_ushort | unsigned short | int/long |
| c_int | int | int/long |
| c_uint | unsigned int | int/long |
| c_long | long | int/long |
| c_ulong | unsigned long | int/long |
| c_longlong | __int64 or longlong | int/long |
| c_ulonglong | unsigned __int64 or unsigned long long | int/long |
| c_float | float | float |
| c_double | double | float |
| c_longdouble | long double float | float |
| c_char_p | char * | string or None |
| c_wchar_p | wchar_t * | unicode or None |
| c_void_p | void * | int/long or None |
设置函数的参数类型使用函数的argtypes属性,直接赋值为一个ctypes类型的列表或元组。设置函数的返回值类型使用函数的restype属性。下面是示例代码:
python中,默认函数返回值是c_int型,此类型可以不用显示设置函数的restype属性,如果是参数类型是c_int型则需要设置。
```python
fun.argtypes = (c_int, c_int,c_int,c_void_p) #设置函数参数类型为 int,int,int,void *
fun.restype = c_float #设置返回值类