Реализация offsetof () для структур в Python ctypes - PullRequest
5 голосов
/ 18 января 2011

Кажется, я не могу реализовать offsetof для структуры в ctypes.Я видел FAQ для 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.

Есть идеи?Спасибо!

Ответы [ 2 ]

15 голосов
/ 18 января 2011
class Dog(Structure):
    _fields_ = [('name', c_char_p), ('weight', c_int)]

Dog.name.offset
# 0
Dog.weight.offset
# 4 (on my 32-bit system)

Задача превращения этого в метод оставлена ​​читателю:)

0 голосов
/ 20 декабря 2013

Проблема в том, что элементы структуры иногда возвращаются как простые типы Python. Например

class Test(Structure):
    _fields_ = [('f1', c_char), ('f2', c_char * 0)]

тип (Test (). F1) является типом (Test (). F2): str

...