Python中的ctypes使用场景

 更新时间:2026年02月12日 09:35:24   作者:方安乐  
ctypes是Python与C世界之间的一座桥梁,强大但需谨慎使用,对于更复杂或高频的交互,也可考虑cffi、pybind11或Cython等替代方案,本文给大家介绍Python中的ctypes,感兴趣的朋友一起看看吧

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, %s\n", 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 转换仍有开销。

简单示例:调用 C 标准库的abs

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中时间模块的基本使用教程

    python中时间模块的基本使用教程

    这篇文章主要给大家介绍了关于python中时间模块的基本使用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用python具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • 使用XML库的方式,实现RPC通信的方法(推荐)

    使用XML库的方式,实现RPC通信的方法(推荐)

    下面小编就为大家带来一篇使用XML库的方式,实现RPC通信的方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Python之打印日志库(logging)

    Python之打印日志库(logging)

    这篇文章主要介绍了Python之打印日志库(logging),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Python基于百度AI实现OCR文字识别

    Python基于百度AI实现OCR文字识别

    这篇文章主要介绍了Python基于百度AI实现OCR文字识别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • python抓取百度首页的方法

    python抓取百度首页的方法

    这篇文章主要介绍了python抓取百度首页的方法,涉及Python使用urllib模块实现页面抓取的相关技巧,需要的朋友可以参考下
    2015-05-05
  • python使用 __init__初始化操作简单示例

    python使用 __init__初始化操作简单示例

    这篇文章主要介绍了python使用 __init__初始化操作,结合实例形式分析了Python面向对象程序设计中使用__init__进行初始化操作相关技巧与注意事项,需要的朋友可以参考下
    2019-09-09
  • python爬虫 基于requests模块发起ajax的get请求实现解析

    python爬虫 基于requests模块发起ajax的get请求实现解析

    这篇文章主要介绍了python爬虫 基于requests模块发起ajax的get请求实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • Python isalnum()函数的具体使用

    Python isalnum()函数的具体使用

    本文主要介绍了Python isalnum()函数的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • python 实现倒计时功能(gui界面)

    python 实现倒计时功能(gui界面)

    这篇文章主要介绍了python 实现倒计时功能(gui界面),帮助大家更好的理解和使用python,感兴趣的朋友可以了解下
    2020-11-11
  • 用Python的Flask框架结合MySQL写一个内存监控程序

    用Python的Flask框架结合MySQL写一个内存监控程序

    这篇文章主要介绍了用Python的Flask框架结合MySQL些一个内存监控程序的例子,并且能将结果作简单的图形化显示,需要的朋友可以参考下
    2015-11-11

最新评论