我有一个来自 C++ 库的
float
指针 p
,我想在 Python 模块中增加它。当我尝试编写 p + distance
时,我收到错误消息,指出 +
的运算符 LP_c_float
未定义。
一个可能的解决方案是使用
advance(p, distance)
代替,其中
def advance(pointer, distance, type = ctypes.c_float):
return ctypes.cast(ctypes.cast(pointer, ctypes.c_voidp).value + distance, ctypes.POINTER(type))
然而,演员
ctypes.c_voidp
真的有必要吗?为什么没有为 LP_c_float
定义加法(或者为什么它没有类似的 value
字段)?
您在 LP_c_float 类型(其中 LP_c_float 代表 ctypes 库中的“指向浮点数的指针”)上直接添加时遇到问题的原因源于 Python 的 ctypes 库设计为与 C 数据类型交互的方式。在C中,指针算术是常见的操作,但在Python这种高级语言中,直接内存操作和指针算术并不是原生概念。这就是为什么你不能直接向 ctypes 指针类型(例如 LP_c_float)添加整数来使指针前进。
对 ctypes.c_voidp 的强制转换是必要的,因为它将指针转换为通用 void 指针,该指针本质上是指向未指定数据类型的指针。 ctypes.c_voidp 对象的 value 属性获取或设置指针作为简单的 Python 整数。这允许您直接对其执行算术,这对于更具体的 ctypes 指针类型来说是不可能的。将指针地址调整到所需的距离后,然后将其转换回原始指针类型,以便可以取消引用或按预期使用它。
没有为 LP_c_float 或类似的 ctypes 指针类型定义直接加法,因为 Python 的内存处理模型比 C 的模型更安全、更抽象。 Python 的 ctypes 库提供了与低级内存和 C 库交互的机制,但它强制执行更严格的模型来防止不安全内存操作可能引起的常见错误,例如缓冲区溢出、内存损坏和未定义的行为。这种设计选择需要使用 ctypes.cast() 等函数进行指针算术,确保谨慎执行此类操作并了解潜在风险。