La mise en œuvre offsetof () pour les structures en ctypes python
Question
Je ne peux pas sembler mettre en œuvre offsetof pour une structure en ctypes. Je l'ai vu la FAQ ctypes, mais soit il ne fonctionne pas, ou Je ne peux pas comprendre les détails.
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
Il semble addressof()
ne fonctionne pas sur les membres de la structure (par exemple d.weight
). j'ai essayé
autres impliquant pointer()
et byref()
, mais pas de chance.
Bien sûr, je veux que cela fonctionne sur toutes les architectures, quelle que soit la taille d'un pointeur, et quels que soient les effets de rembourrage, alors s'il vous plaît ne dites pas résumer simplement le sizeof () pour tous les éléments précédents, à moins que vous pouvez vous assurer que vous prenez tout rembourrage C compilateur ajoute en compte.
Toutes les idées? Merci!
La solution
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 tâche de transformer cela en une méthode est laissée au lecteur:)
Autres conseils
Le problème est que les membres de la structure sont parfois retournés comme types de python simples. Par exemple
class Test(Structure):
_fields_ = [('f1', c_char), ('f2', c_char * 0)]
Type (Test (). F1) est de type (Test (). F2) est str