在原地更新ctypes指针

2 投票
2 回答
1621 浏览
提问于 2025-04-18 00:59

出于各种原因,我想直接更新一个ctypes指针的值。换句话说,我想修改这个指针对象所包裹的内部缓冲区。这里有一种可能的方法:

from ctypes import *

a = pointer(c_int(123))
b = pointer(c_int(456))

memmove(addressof(a), addressof(b), sizeof(c_void_p))
a._objects.clear()
a._objects.update(b._objects)

现在,a.contents会返回c_long(456)。不过,玩弄一下<_objects>这个属性似乎太关注实现细节了(这样做会不会有问题呢?)。有没有更合适的方法来做到这一点?

2 个回答

0

指针就是一个变量,它用来存储内存地址。所以,当你调用 memmove(addressof(a), addressof(b),...) 时,实际上是把 b 里存的地址复制到了 a 里,这样 a 就指向了和 b 一样的内存位置。如果你就是想这样,那就完成了。

但如果你想要的是把 a 指向的整数的值设置成和 b 指向的整数的值一样,那你需要把 b 指向的内存里的内容复制到 a 指向的内存里。就像这样...

memmove(cast(a, c_void_p).value, cast(b, c_void_p).value, sizeof(c_int))

现在指针 a 指向的内存地址里存的值和 b 指向的内存里的值相似

在这两种情况下,_objects 属性其实都不是必须的(这是我个人的看法)。

抱歉这篇帖子有点无聊。不过我担心这就是使用指针的(唯一?)方法了 :)

3

因为eryksun还没有发布他的答案,我就自己把它加在这里。这是正确的做法:

from ctypes import *

a = pointer(c_int(123))
b = pointer(c_int(456))

tmp = pointer(a)[0]
tmp.contents = b.contents

现在 a.contents = c_int(456)。关键是 tmpa 共享一个缓冲区(这就是你会发现 tmp._b_needsfree_ == 0 的原因)。

撰写回答