【问题标题】:Implementing offsetof() for structures in Python ctypes为 Python ctypes 中的结构实现 offsetof()
【发布时间】: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 编译器添加考虑。

有什么想法吗?谢谢!

【问题讨论】:

    标签: python c padding ctypes ffi


    【解决方案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] 做的工作,但它只是稍微不那么难看......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    相关资源
    最近更新 更多