Master Python ctypes: Call Windows DLLs and APIs Like a Pro
This comprehensive guide explains how Python can interface with C dynamic link libraries using the ctypes module, covering installation, data types, pointer manipulation, buffer creation, DLL loading, function calling, Windows API interactions, and practical code examples for system-level programming.
大家好,我是Python进阶者。
前言
动态链接库(DLL)想必大家都不陌生了吧,C/C++编程经常会用到,那么,它跟我们的Python有什么关系?Python本身是用C写的,并且可以调用C函数,这一点在Pywin32中有所体现。下面我们详细了解Python使用动态链接库的方式。
一、神秘的模块
我们都知道C语言是比较靠近底层的语言,所以要使用动态链接库就需要给Python和C构建一座桥梁。今天要说的这座桥梁就是 Ctypes 。
二、安装并导入Ctypes
系统自带该模块,若没有,安装Pywin32也会包含。
from ctypes import *三、认识动态链接库
在Linux系统中表现为“.so”后缀文件,在Windows中表现为“.dll”。
四、初步了解Ctypes
安装后需要查看Ctypes的所有函数及方法。
五、Ctypes的基本用法
1). 数据类型
Ctypes完美契合C的数据类型,下面是常用类型对应表:
ctypes 类型
C 类型
Python 类型
c_bool
_Bool
bool (1)
c_char
char
单字符字节对象
c_wchar
wchar_t
单字符字符串
c_byte
char
整型
c_ubyte
unsigned char
整型
c_short
short
整型
c_ushort
unsigned short
整型
c_int
int
整型
c_uint
unsigned int
整型
c_long
long
整型
c_ulong
unsigned long
整型
c_longlong
__int64 或 long long
整型
c_ulonglong
unsigned __int64 或 unsigned long long
整型
c_size_t
size_t
整型
c_ssize_t
ssize_t 或 Py_ssize_t
整型
c_float
float
浮点数
c_double
double
浮点数
c_longdouble
long double
浮点数
c_char_p
char * (以 NUL 结尾)
字节串对象或 None
c_wchar_p
wchar_t * (以 NUL 结尾)
字符串或 None
c_void_p
void *
int 或 None
这些类型可以直接在Python中使用。
2). 操作变量
访问变量的值: it.value 修改变量的值:
it.value = 43 # 直接赋值,即可修改3). 创建指针
# 强指针
pt = pointer(it) # 定义指针,指向变量 pt
pt.contents # 指针所指的对象
# 弱指针
byref(it, 4) # 偏移量4). 缓冲区创建
字符缓冲:
p = create_string_buffer(4) # 创建4字节缓冲区,初始化为空字节
create_string_buffer(b"Hello") # 包含空字符结尾的字符串缓冲区
create_string_buffer(b"Hello", 10) # 创建10字节缓冲区
print(sizeof(p), repr(p.raw))Unicode 缓冲:
a = create_unicode_buffer(5) # 创建5字符的unicode缓冲区
create_unicode_buffer('ffsa')
create_unicode_buffer('ffsa', 5) # 结尾空字符
print(sizeof(a))5). 调用动态链接库
CDLL('xx.dll')
OleDLL('xx.dll')
PyDLL('xx.dll')
WinDLL('xx.dll')
cdll.LoadLibrary('xx.dll')
... # 共16种调用方式6). 查找动态链接库
from ctypes.util import find_library
find_library('user32') # 查找7). 调用DLL函数
dll = windll.LoadLibrary('xx.dll')
dll.函数名8). Windows API 示例(MessageBox)
from ctypes import c_int, WINFUNCTYPE, windll
from ctypes.wintypes import HWND, LPCWSTR, UINT
tp = WINFUNCTYPE(c_int, HWND, LPCWSTR, LPCWSTR, UINT)
bt = ((1, "hwnd", 0), (1, "text", "我是内容"), (1, "caption", "我是标题"), (1, "type", 0))
MessageBox = tp(("MessageBoxW", windll.user32), bt)
MessageBox()
ab = MessageBox(caption='提示', text='我也是内容')9). 获取所有顶层窗口
from ctypes import *
from ctypes import wintypes
res = WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM)
def win(h, p):
le = user32.GetWindowTextLengthW(h) + 1
buffer = create_unicode_buffer(le)
user32.GetWindowTextW(h, buffer, le)
print(buffer.value)
return True
user32 = windll.LoadLibrary('user32.dll')
user32.EnumWindows(res(win), 0)六、总结
Ctypes对于想要在Python中使用C语言库的开发者非常友好,提供了丰富的数据类型、指针操作、DLL加载和系统 API 调用的能力,使得在 Python 中进行底层系统编程变得相对简单。
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Python Crawling & Data Mining
Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
