如何将PyCapsule类型的图像句柄转换为ctypes.c_void_p?
PyCapsule 转 ctypes.c_void_p 的实现方法
PyCapsule 是 Python 用来封装 C 语言指针的容器,不能直接通过 ctypes.py_object 转换,必须用 Python C API 中的 PyCapsule_GetPointer 函数提取内部的原生指针,再封装成 ctypes.c_void_p。
具体实现步骤
- 加载 Python 的动态链接库(不同平台路径不同)
- 定义
PyCapsule_GetPointer的函数原型 - 调用函数提取指针并转换为
ctypes.c_void_p
代码示例
import ctypes import sys # 加载 Python 动态库,根据系统自动适配 if sys.platform.startswith('win'): python_lib = ctypes.WinDLL(f'python{sys.version_info.major}{sys.version_info.minor}.dll') elif sys.platform.startswith('linux'): python_lib = ctypes.CDLL(f'libpython{sys.version_info.major}.{sys.version_info.minor}.so') elif sys.platform.startswith('darwin'): python_lib = ctypes.CDLL(f'libpython{sys.version_info.major}.{sys.version_info.minor}.dylib') else: raise RuntimeError(f"Unsupported platform: {sys.platform}") # 定义 PyCapsule_GetPointer 的函数原型 python_lib.PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p] python_lib.PyCapsule_GetPointer.restype = ctypes.c_void_p # 假设 capsule 是你拿到的 PyCapsule 对象 # 第二个参数是 capsule 的名称(如果创建时指定了,要填对应的值;不确定可以传 NULL,即 b'') capsule_name = b'' # 或者对应 capsule 创建时的名称 void_ptr = python_lib.PyCapsule_GetPointer(capsule, capsule_name) if not void_ptr: # 转换失败,可能是 capsule 无效或名称不匹配 raise ValueError("Failed to get pointer from PyCapsule") # 现在 void_ptr 就是可以传给另一个库的 ctypes.c_void_p 类型 print(f"Converted void pointer: {void_ptr}")
注意事项
- capsule 名称匹配:如果创建 PyCapsule 时指定了名称(比如
PyCapsule_New的第三个参数),调用PyCapsule_GetPointer时必须传入相同的名称字节串,否则会返回 NULL。如果不确定名称,可以传空字节串b''(对应 C 中的 NULL),但部分严格的 Capsule 会要求名称匹配。 - 错误检查:一定要判断返回的指针是否为 NULL,避免后续调用出现崩溃。
- Python 版本兼容:代码中根据版本号加载对应库,确保和当前运行的 Python 版本一致。
内容的提问来源于stack exchange,提问作者ysonishi
相关产品推荐
相关产品推荐

