diff options
author | Armin Rigo <arigo@tunes.org> | 2012-09-18 19:37:12 +0200 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2012-09-18 19:37:12 +0200 |
commit | 372f235b1278fb57f1d40654a3b1b0c8472cede2 (patch) | |
tree | 409862086a92ad66effa50c91ec767a9d5b65a01 /cffi/backend_ctypes.py | |
parent | bd55fb00e58891a6ae7404b56d6ba71066d7dba4 (diff) | |
download | cffi-372f235b1278fb57f1d40654a3b1b0c8472cede2.tar.gz |
ffi.addressof(struct, field).
Diffstat (limited to 'cffi/backend_ctypes.py')
-rw-r--r-- | cffi/backend_ctypes.py | 31 |
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) |