在Python中递增浮点指针
我在一个C++库里有一个指向浮点数的指针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
字段)呢?
1 个回答
2
指针本身不能直接增加,只能增加它所指向的值。你可以用简单的索引方法来获取下一个值,下面有个例子。
假设你有一个指向数据数组第一个元素的 float*
指针,下面的 p
就是这个指针的用法:
import ctypes as ct
data = (3 * ct.c_float)(1.5, 2.5, 3.5) # (C) float data[3] = {1.5, 2.5, 3.5};
p = ct.POINTER(ct.c_float)(data) # (C) float* p = data;
print(p, p[0], p[1])
p[0] += 1
p[1] += 2
print(p, p[0], p[1])
p.contents.value += 2 # (C) *p += 1
print(p, p[:len(data)]) # If you know the length, slice data into Python list
输出结果:
<__main__.LP_c_float object at 0x0000019FA3E116D0> 1.5 2.5
<__main__.LP_c_float object at 0x0000019FA3E116D0> 2.5 4.5
<__main__.LP_c_float object at 0x0000019FA3E116D0> [4.5, 4.5, 3.5]
如果你想要让指针本身增加,就得费点劲。下面的代码可以让指针增加一个元素,比如在C语言中可以写成 p += 1
。
# Get the C address of the first element (Python int)
# and add the size of an element in bytes.
new_address = ct.addressof(p.contents) + ct.sizeof(ct.c_float)
# c_void_p() takes a Python int for initialization.
# Other pointers don't, so a cast is needed.
p = ct.cast(ct.c_void_p(new_address), ct.POINTER(ct.c_float))
print(p, p[:2])
输出结果:
<__main__.LP_c_float object at 0x0000019FA3E10F50> [4.5, 3.5]
如你所见,这样做是比较耗费资源的。如果必须要做指针运算,建议在C语言中直接进行。