为 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 给出 , 。 (即 c_char 和 c_char_Array。) @Andris:从中恢复类型的唯一方法是解析repr(Test.f1),这非常难看 它看起来像gc.get_referents(Test.f1)[0] 做的工作,但它只是稍微不那么难看......

以上是关于为 Python ctypes 中的结构实现 offsetof()的主要内容,如果未能解决你的问题,请参考以下文章

ctype中的结构

使用 ctypes 将 python dict 转换为结构

指南:使用ctypes优化Python代码

ctypes给扩展模块中的函数传递数组和结构体

使用 ctypes 传递结构指针

在 Python ctypes 中转换为数组