为 Python ctypes 中的结构实现 offsetof()
Posted
技术标签:
【中文标题】为 Python ctypes 中的结构实现 offsetof()【英文标题】:Implementing offsetof() for structures in Python ctypes 【发布时间】:2011-06-10 19:12:09 【问题描述】:我似乎无法为 ctypes 中的结构实现 offsetof。我看过 FAQ for ctypes,但要么不起作用,要么 我无法弄清楚细节。
Python 2.6.4 (r264:75706, Dec 19 2010, 13:04:47) [C] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> class Dog(Structure):
... _fields_ = [('name', c_char_p), ('weight', c_int)]
... def offsetof(self, field):
... return addressof(field) - addressof(self)
...
>>> d = Dog('max', 80)
>>> d.offsetof(d.weight)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in offsetof
TypeError: invalid type
>>> d.offsetof(weight)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'weight' is not defined
>>> d.offsetof('weight')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in offsetof
TypeError: invalid type
似乎addressof()
不适用于结构成员(例如d.weight
)。我努力了
其他涉及pointer()
和byref()
的事情,但没有运气。
当然,我希望它适用于所有架构,无论指针大小如何, 并且不管填充的效果如何,所以请不要说只求和 sizeof() 对于所有以前的元素,除非您可以确保您正在使用任何填充 C 编译器添加考虑。
有什么想法吗?谢谢!
【问题讨论】:
【参考方案1】:class Dog(Structure):
_fields_ = [('name', c_char_p), ('weight', c_int)]
Dog.name.offset
# 0
Dog.weight.offset
# 4 (on my 32-bit system)
将其转化为方法的任务留给读者 :)
【讨论】:
谢谢!天哪,这很容易。我在 ctypes 的文档中找不到它,但我会重新阅读它。 ctypes 的文档有些不完整——也许它丢失了。 @zhangyoufu:不清楚您所说的“不起作用”和“用于数组”是什么意思。你的意思是这不会为包含数组的结构产生正确的偏移量吗?为我工作:ideone.com/IT8iee @SvenMarnach:对不起。我的代码有错误。它有效。【参考方案2】:问题是结构成员有时会作为普通的 python 类型返回。 例如
class Test(Structure):
_fields_ = [('f1', c_char), ('f2', c_char * 0)]
type(Test().f1) is type(Test().f2) is str
【讨论】:
如果您使用类本身,而不是实例,则不是问题 - 如接受的答案:Test.f1, Test.f2 给出repr(Test.f1)
,这非常难看
它看起来像gc.get_referents(Test.f1)[0]
做的工作,但它只是稍微不那么难看......以上是关于为 Python ctypes 中的结构实现 offsetof()的主要内容,如果未能解决你的问题,请参考以下文章