Python基础(①①Ctypes)
ctypes 是什么?
ctypes 是 Python 标准库自带的模块(无需额外安装),主要作用是 调用 C 语言编写的动态链接库(如 Windows 的 .dll、Linux 的 .so、macOS 的 .dylib),实现 Python 与 C 代码的交互(和 Cython 不同,ctypes 是 “直接调用现成的 C 库”,而 Cython 是 “将 Python 风格代码编译为 C 扩展”)
场景 1:调用 Windows 系统自带 DLL
user32.dll
是 Windows 系统中负责窗口管理的重要 DLL,包含很多与窗口、消息框相关的功能。
"弹出消息框"代码
import ctypes
import sysdef show_message_box():if not sys.platform.startswith('win32'):print("这个程序只能在Windows系统上运行哦!")returnuser32 = ctypes.WinDLL('user32', use_last_error=True)# 使用MessageBoxW而不是MessageBoxA,支持Unicodeuser32.MessageBoxW(None,"你好!这是用user32.dll弹出的消息框", # 中文现在能正常显示了"消息框标题",0x00000001 | 0x00000040 # 样式不变)if __name__ == "__main__":show_message_box()print("消息框已关闭")
获取屏幕分辨率代码
import ctypes
import sysdef get_screen_resolution():if not sys.platform.startswith('win32'):print("这个程序只能在Windows系统上运行")returnuser32 = ctypes.WinDLL('user32')# 获取屏幕宽度width = user32.GetSystemMetrics(0) # 0表示SM_CXSCREEN,屏幕宽度# 获取屏幕高度height = user32.GetSystemMetrics(1) # 1表示SM_CYSCREEN,屏幕高度print(f"屏幕分辨率: {width}x{height}")if __name__ == "__main__":get_screen_resolution()
场景 2:调用自己写的C++
步骤 1:编写 C++ 代码(生成 DLL)
首先创建一个简单的 C++ 文件(例如mydll.cpp
),注意要使用__declspec(dllexport)
导出函数,以便其他程序调用:
// mydll.cpp
#include <iostream>
#include <string>// 导出函数声明,extern "C" 确保函数名不被C++编译器修饰
extern "C" __declspec(dllexport) int add(int a, int b) {return a + b;
}extern "C" __declspec(dllexport) const char* get_message() {// 返回字符串时要注意:确保内存有效(这里用静态字符串)return "Hello from C++ DLL!";
}extern "C" __declspec(dllexport) void print_message(const char* msg) {std::cout << "Received: " << msg << std::endl;
}
步骤 2:打开 VS2022 的命令行工具
按下Win + S
,搜索并打开 "x64 Native Tools Command Prompt for VS 2022"(这是 VS2022 的 64 位命令行工具,已配置好编译环境)
在打开的命令行工具中,切换到mydll.cpp
所在的目录(例如cd D:\myproject
),然后执行以下命令:
cl /LD /EHsc mydll.cpp
/LD:指定生成 DLL(动态链接库)
/EHsc:启用 C++ 异常处理(可选,但推荐)
mydll.cpp:你的源代码文件
执行成功后,会在当前目录生成 3 个文件:
mydll.dll:我们需要的动态链接库
mydll.lib:导入库(链接时使用,Python 调用 DLL 时不需要)
mydll.obj:编译中间文件(可忽略)
步骤 3:用 Python 的 ctypes 调用 DLL
import ctypes
import osdef call_my_dll():# 加载DLL(替换为你的DLL实际路径)dll_path = os.path.join(os.path.dirname(__file__), "mydll.dll")mydll = ctypes.CDLL(dll_path)# 1. 调用add函数(整数相加)# 设置参数和返回值类型(可选,但推荐)mydll.add.argtypes = [ctypes.c_int, ctypes.c_int]mydll.add.restype = ctypes.c_intresult = mydll.add(3, 5)print(f"3 + 5 = {result}")# 2. 调用get_message函数(获取字符串)mydll.get_message.argtypes = []mydll.get_message.restype = ctypes.c_char_p # 表示返回C风格字符串message = mydll.get_message()print(f"从DLL获取的消息: {message.decode('utf-8')}")# 3. 调用print_message函数(传递字符串)mydll.print_message.argtypes = [ctypes.c_char_p]mydll.print_message.argtypes = [ctypes.c_char_p]mydll.print_message(b"Hello from Python!") # 传递字节串if __name__ == "__main__":call_my_dll()
123