summaryrefslogtreecommitdiff
path: root/cffi/backend_ctypes.py
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2012-09-18 19:37:12 +0200
committerArmin Rigo <arigo@tunes.org>2012-09-18 19:37:12 +0200
commit372f235b1278fb57f1d40654a3b1b0c8472cede2 (patch)
tree409862086a92ad66effa50c91ec767a9d5b65a01 /cffi/backend_ctypes.py
parentbd55fb00e58891a6ae7404b56d6ba71066d7dba4 (diff)
downloadcffi-372f235b1278fb57f1d40654a3b1b0c8472cede2.tar.gz
ffi.addressof(struct, field).
Diffstat (limited to 'cffi/backend_ctypes.py')
-rw-r--r--cffi/backend_ctypes.py31
1 files changed, 28 insertions, 3 deletions
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
index 17b9c36..7fef4dc 100644
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -718,13 +718,17 @@ class CTypesBackend(object):
btypes = [BField for (fname, BField, bitsize) in fields]
bitfields = [bitsize for (fname, BField, bitsize) in fields]
#
+ bfield_types = {}
cfields = []
for (fname, BField, bitsize) in fields:
if bitsize < 0:
cfields.append((fname, BField._ctype))
+ bfield_types[fname] = BField
else:
cfields.append((fname, BField._ctype, bitsize))
+ bfield_types[fname] = Ellipsis
struct_or_union._fields_ = cfields
+ CTypesStructOrUnion._bfield_types = bfield_types
#
@staticmethod
def _create_ctype_obj(init):
@@ -1044,10 +1048,31 @@ class CTypesBackend(object):
def getcname(self, BType, replace_with):
return BType._get_c_name(replace_with)
- def addressof(self, BTypePtr, cdata):
- if not isinstance(cdata, CTypesBaseStructOrUnion):
+ def typeoffsetof(self, BType, fieldname):
+ if fieldname is not None and issubclass(BType, CTypesGenericPtr):
+ BType = BType._BItem
+ if not issubclass(BType, CTypesBaseStructOrUnion):
+ raise TypeError("expected a struct or union ctype")
+ if fieldname is None:
+ return (BType, 0)
+ else:
+ BField = BType._bfield_types[fieldname]
+ if BField is Ellipsis:
+ raise TypeError("not supported for bitfields")
+ return (BField, BType._offsetof(fieldname))
+
+ def rawaddressof(self, BTypePtr, cdata, offset):
+ if isinstance(cdata, CTypesBaseStructOrUnion):
+ ptr = ctypes.pointer(type(cdata)._to_ctypes(cdata))
+ elif isinstance(cdata, CTypesGenericPtr):
+ ptr = type(cdata)._to_ctypes(cdata)
+ else:
raise TypeError("expected a <cdata 'struct-or-union'>")
- ptr = ctypes.pointer(type(cdata)._to_ctypes(cdata))
+ if offset != 0:
+ ptr = ctypes.cast(
+ ctypes.c_void_p(
+ ctypes.cast(ptr, ctypes.c_void_p).value + offset),
+ type(ptr))
return BTypePtr._from_ctypes(ptr)