La implementación de offsetof () para estructuras en ctypes Python
Pregunta
Me parece que no puede poner en práctica offsetof de una estructura en la ctypes. He visto el FAQ para ctypes , pero o bien no funciona, o No puedo averiguar los detalles.
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
Parece addressof()
no funciona en los miembros de la estructura (por ejemplo d.weight
). Yo he tratado
otras cosas que implican pointer()
y byref()
, pero no hubo suerte.
Por supuesto que quiero que esto funcione en todas las arquitecturas, independientemente del tamaño de un puntero, y con independencia de los efectos de relleno, por lo que no acaba de decir a resumir el sizeof () para todos los elementos anteriores, a menos que pueda asegurarse de que usted está tomando cualquier relleno del C compilador añade en cuenta.
Algunas ideas? Gracias!
Solución
class Dog(Structure):
_fields_ = [('name', c_char_p), ('weight', c_int)]
Dog.name.offset
# 0
Dog.weight.offset
# 4 (on my 32-bit system)
La tarea de convertir esto en un método se deja al lector:)
Otros consejos
El problema es que a veces son miembros de la estructura devueltos como tipos de pitón de civil. Por ejemplo
class Test(Structure):
_fields_ = [('f1', c_char), ('f2', c_char * 0)]
tipo (Test (). F1) es de tipo (Test (). F2) se str