Python中的ctypes使用场景

作者:

文章目录
  • 加载动态链接库 Windows: ctypes.WinDLL / ctypes.CDLL Linux/macOS: ctypes.CDLL 示例: import ctypes libc = ctypes.CDLL(“libc.so.6”) # Linux # 或 msvcrt = ctypes.CDLL(“msvcrt.dll”) # Windows 调用 C 函数 加载后可像普通函数一样调用: result = libc.printf(b”Hello, %sn”, b”world”) 数据类型映射 ctypes 提供了与 C 类型对应的 Python 类型,例如: 示例结构体 class Point(ctypes.Structure): _fields_ = [(“x”, ctypes.c_int), (“y”, ctypes.c_int)] p = Point(10, 20) c_int, c_char, c_double, c_void_p 等 数组:c_int * 10 结构体:继承 ctypes.Structure 联合体:继承 ctypes.Union 指定函数参数和返回类型 默认情况下,ctypes 假设函数返回 c_int,参数按 C 的默认规则转换。 可显式设置: libc.malloc.argtypes = [ctypes.c_size_t] libc.malloc.restype = ctypes.c_void_p 回调函数(Callback) 可将 Python 函数作为 C 函数指针传入:python CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int) def py_cmp(a, b): return a – b cmp_func = CMPFUNC(py_cmp) 内存管理 可通过 ctypes.create_string_buffer() 创建可变内存块 注意:不当使用可能导致段错误(segmentation fault)
  • 调用系统 API(如 Windows API) 复用高性能 C 库(如数学计算、图像处理) 与硬件驱动或嵌入式设备通信 快速原型开发,避免重写 C 代码
  • 平台依赖性:不同操作系统/架构下,库名称、调用约定(calling convention)可能不同。 ABI 兼容性:需确保调用的函数签名与实际一致,否则程序可能崩溃。 安全性:ctypes 绕过了 Python 的内存安全机制,错误使用可能导致严重问题。 性能开销:虽然调用的是原生代码,但频繁的 Python ↔ C 转换仍有开销。
  • import ctypes # 加载 C 标准库(Linux/macOS) libc = ctypes.CDLL(“libc.so.6”) # macOS 可能是 “libc.dylib” # 设置函数签名 libc.abs.argtypes = [ctypes.c_int] libc.abs.restype = ctypes.c_int # 调用 print(libc.abs(-42)) # 输出: 42 在 Windows 上可使用 "msvcrt.dll" 并调用 abs。 总之,ctypes 是 Python 与 C 世界之间的一座桥梁,强大但需谨慎使用。对于更复杂或高频的交互,也可考虑 cffi、pybind11 或 Cython 等替代方案。 到此这篇关于Python中的ctypes的文章就介绍到这了,更多相关Python ctypes内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: python中ctypes使用方法 Python ctypes库底层交互秘籍实例探究 python使用ctypes调用dll遇到的坑解决记录 python中用ctypes模拟点击的实例讲解 python使用ctypes调用扩展模块的实例方法 Python优化技巧之利用ctypes提高执行速度 利用ctypes提高Python的执行速度
  • 目录
    • 主要功能
    • 使用场景
      • 检查屏幕状态
    • 注意事项
      • 简单示例:调用 C 标准库的abs

        ctypes 是 Python 标准库中的一个模块,用于调用动态链接库(如 .dll.so.dylib)中的 C 函数,并与 C 兼容的数据类型进行交互。它允许 Python 程序直接与用 C/C++ 编写的共享库进行交互,而无需编写额外的绑定代码(如使用 Cython 或 SWIG)。这在需要高性能计算、复用已有 C 库或操作系统底层接口时非常有用。

        • 加载动态链接库
          • Windows: ctypes.WinDLL / ctypes.CDLL
          • Linux/macOS: ctypes.CDLL
          • 示例:
        • import ctypes
          libc = ctypes.CDLL("libc.so.6")  # Linux
          # 或
          msvcrt = ctypes.CDLL("msvcrt.dll")  # Windows
        • 调用 C 函数
          • 加载后可像普通函数一样调用:
        • result = libc.printf(b"Hello, %sn", b"world")
        • 数据类型映射
          • ctypes 提供了与 C 类型对应的 Python 类型,例如:
          • 示例结构体
        • class Point(ctypes.Structure):
              _fields_ = [("x", ctypes.c_int),
                          ("y", ctypes.c_int)]
          p = Point(10, 20)
        • c_intc_charc_doublec_void_p 等
          • 数组:c_int * 10
          • 结构体:继承 ctypes.Structure
          • 联合体:继承 ctypes.Union
        • 指定函数参数和返回类型
          • 默认情况下,ctypes 假设函数返回 c_int,参数按 C 的默认规则转换。
          • 可显式设置:
        • libc.malloc.argtypes = [ctypes.c_size_t]
          libc.malloc.restype = ctypes.c_void_p
        • 回调函数(Callback)
          • 可将 Python 函数作为 C 函数指针传入:python
        • CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)
          def py_cmp(a, b):
              return a - b
          cmp_func = CMPFUNC(py_cmp)
        • 内存管理
          • 可通过 ctypes.create_string_buffer() 创建可变内存块
          • 注意:不当使用可能导致段错误(segmentation fault)

        • 调用系统 API(如 Windows API)
        • 复用高性能 C 库(如数学计算、图像处理)
        • 与硬件驱动或嵌入式设备通信
        • 快速原型开发,避免重写 C 代码

         通过cypes加载Windows API的user32.dll动态链接库
         user32.dll是Windows系统中负责用户界面相关功能的核心库,提供了窗口管理、消息处理等功能

        def check_screen_state():
                user32 = ctypes.windll.user32 
                #GetDC函数用于获取指定窗口的设备上下文(Device Context),0表示获取整个屏幕的DC,而不是特定窗口的
                hdc = user32.GetDC(0)
                try:
                    # 获取设备的特定能力值,109对应WindowsAPI中的SM_CMONITORS常量,用于获取系统中显示器的数量
                    result = user32.GetDeviceCaps(hdc, 109) # 目的是检查系统中是否有显示器连接
                    if result == 0:
                        current_state = 'off'
                    else:
                        '''
                        SystemParametersInfoW是WindowsAPI中的一个核心函数,用于获取或设置各种系统参数。
                        后缀W表示这是Unicode版本的函数,用于处理宽字符
                        BOOL SystemParametersInfoW(
                            UINT  uiAction,      // 要执行的操作
                            UINT  uiParam,       // 操作相关的参数
                            PVOID pvParam,       // 数据缓冲区指针
                            UINT  fWinIni        // 更新配置文件的标志
                        );
                        - 当调用 SystemParametersInfoW(16, 0, None, 0) 时:
                        - uiAction = SPI_GETSCREENSAVERRUNNING (16)
                        - uiParam = 0 (此操作不需要额外参数)
                        - pvParam = None (在 Python 中,这里会返回布尔值)
                        - fWinIni = 0 (不需要更新配置文件)
                        - 返回值:如果屏幕保护程序正在运行,返回非零值;否则返回 0。
                        '''
                        is_screen_saver_running = user32.SystemParametersInfoW(16, 0, None, 0) 
                        if is_screen_saver_running:
                            current_state = 'screensaver' // 屏幕保护程序运行
                        else:
                            # 参数 114 用于检查显示器电源管理是否已激活,对应WindowsAPI中的常量SPI_GETTPOWEROFFACTIVE
                            is_monitor_off = user32.SystemParametersInfoW(114, 0, None, 0) 
                            if is_monitor_off:
                                current_state = 'off' // 屏幕关闭
                            else:
                                current_state = 'on' // 屏幕亮起
                except:
                    current_state = 'unknown' // 屏幕状态未知
                finally:
                    user32.ReleaseDC(0, hdc)
                return current_state
            

        • 平台依赖性:不同操作系统/架构下,库名称、调用约定(calling convention)可能不同。
        • ABI 兼容性:需确保调用的函数签名与实际一致,否则程序可能崩溃。
        • 安全性ctypes 绕过了 Python 的内存安全机制,错误使用可能导致严重问题。
        • 性能开销:虽然调用的是原生代码,但频繁的 Python ↔ C 转换仍有开销。

        import ctypes
        # 加载 C 标准库(Linux/macOS)
        libc = ctypes.CDLL("libc.so.6")  # macOS 可能是 "libc.dylib"
        # 设置函数签名
        libc.abs.argtypes = [ctypes.c_int]
        libc.abs.restype = ctypes.c_int
        # 调用
        print(libc.abs(-42))  # 输出: 42

        在 Windows 上可使用 "msvcrt.dll" 并调用 abs

        总之,ctypes 是 Python 与 C 世界之间的一座桥梁,强大但需谨慎使用。对于更复杂或高频的交互,也可考虑 cffipybind11 或 Cython 等替代方案。

        到此这篇关于Python中的ctypes的文章就介绍到这了,更多相关Python ctypes内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

        您可能感兴趣的文章:

        • python中ctypes使用方法
        • Python ctypes库底层交互秘籍实例探究
        • python使用ctypes调用dll遇到的坑解决记录
        • python中用ctypes模拟点击的实例讲解
        • python使用ctypes调用扩展模块的实例方法
        • Python优化技巧之利用ctypes提高执行速度
        • 利用ctypes提高Python的执行速度

        站内搜索