Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing offsetof() for structures in Python ctypes

I cannot seem to implement offsetof for a structure in ctypes. I have seen the FAQ for ctypes, but either it doesn't work, or I cannot figure out the details.

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

It seems addressof() does not work on structure members (e.g. d.weight). I have tried other things involving pointer() and byref(), but no luck.

Of course I want this to work on all architectures, regardless of the size of a pointer, and regardless of the effects of padding, so please don't say to just sum the sizeof() for all previous elements, unless you can ensure that you're taking any padding the C compiler adds into account.

Any ideas? Thanks!

like image 210
samf Avatar asked Jan 18 '11 00:01

samf


1 Answers

class Dog(Structure):
    _fields_ = [('name', c_char_p), ('weight', c_int)]

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

The task of turning this into a method is left to the reader :)

like image 124
Sven Marnach Avatar answered Oct 21 '22 00:10

Sven Marnach