简化python ctypes库调用API的封装
使用ctypes库调用C的函数, 需要进行封装. 如下所示:
# 对结构的封装
class STARTUPINFOEX(Structure):
""" STARTUPINFOEX structure """
_fields_ = [("StartupInfo", STARTUPINFO),
("lpAttributeList", POINTER(PVOID))]
# 对函数的封装
UpdateProcThreadAttribute = windll.kernel32.UpdateProcThreadAttribute
UpdateProcThreadAttribute.argtype = [
POINTER(PVOID),
DWORD,
POINTER(DWORD),
PVOID,
SIZE_T,
PVOID,
POINTER(SIZE_T)
]
UpdateProcThreadAttribute.restype = BOOL
这个过程比较繁琐. 我做了一下优化, 简化使用场景如下:
CreatePipe = my_api.cdef('''
WINBASEAPI
BOOL
WINAPI
CreatePipe(
_Out_ PHANDLE hReadPipe,
_Out_ PHANDLE hWritePipe,
_In_opt_ LPVOID lpPipeAttributes,
_In_ DWORD nSize
);
''')
用户只需要把C语言定义的函数描述拷贝下来, 剩下的封装工作就自动完成了.
结构也是同样的道理:
COORD,PCOORD = my_api.cdef('''
typedef struct _COORD {
SHORT X;
SHORT Y;
} COORD, *PCOORD;
''')
不仅如此, 通过访问函数或者结构的typing_notion
属性, 可以自动生成类型注解相关的代码, 如下所示:
def CreatePipe(hReadPipe:PHANDLE,hWritePipe:PHANDLE,lpPipeAttributes:LPVOID,nSize:DWORD)->BOOL:pass
CreatePipe = my_api.cdef('''
WINBASEAPI
BOOL
WINAPI
CreatePipe(
_Out_ PHANDLE hReadPipe,
_Out_ PHANDLE hWritePipe,
_In_opt_ LPVOID lpPipeAttributes,
_In_ DWORD nSize
);
''')
print(CreatePipe.typing_notion)
# 输出: def CreatePipe(hReadPipe:PHANDLE,hWritePipe:PHANDLE,lpPipeAttributes:LPVOID,nSize:DWORD)->BOOL:pass
这样就可以享受类型注解的好处了(比如代码自动补全), 同时也不影响函数的功能.