在Python中递增浮点指针

0 投票
1 回答
68 浏览
提问于 2025-04-14 15:31

我在一个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语言中直接进行。

撰写回答