summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/ctypes/__init__.py28
1 files changed, 28 insertions, 0 deletions
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py
index bd4b943..6a6053e 100644
--- a/Lib/ctypes/__init__.py
+++ b/Lib/ctypes/__init__.py
@@ -133,6 +133,18 @@ elif _os.name == "posix":
from _ctypes import sizeof, byref, addressof, alignment, resize
from _ctypes import _SimpleCData
+def _check_size(typ, typecode=None):
+ # Check if sizeof(ctypes_type) against struct.calcsize. This
+ # should protect somewhat against a misconfigured libffi.
+ from struct import calcsize
+ if typecode is None:
+ # Most _type_ codes are the same as used in struct
+ typecode = typ._type_
+ actual, required = sizeof(typ), calcsize(typecode)
+ if actual != required:
+ raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
+ (typ, actual, required))
+
class py_object(_SimpleCData):
_type_ = "O"
def __repr__(self):
@@ -140,18 +152,23 @@ class py_object(_SimpleCData):
return super(py_object, self).__repr__()
except ValueError:
return "%s(<NULL>)" % type(self).__name__
+_check_size(py_object, "P")
class c_short(_SimpleCData):
_type_ = "h"
+_check_size(c_short)
class c_ushort(_SimpleCData):
_type_ = "H"
+_check_size(c_ushort)
class c_long(_SimpleCData):
_type_ = "l"
+_check_size(c_long)
class c_ulong(_SimpleCData):
_type_ = "L"
+_check_size(c_ulong)
if _calcsize("i") == _calcsize("l"):
# if int and long have the same size, make c_int an alias for c_long
@@ -160,15 +177,19 @@ if _calcsize("i") == _calcsize("l"):
else:
class c_int(_SimpleCData):
_type_ = "i"
+ _check_size(c_int)
class c_uint(_SimpleCData):
_type_ = "I"
+ _check_size(c_uint)
class c_float(_SimpleCData):
_type_ = "f"
+_check_size(c_float)
class c_double(_SimpleCData):
_type_ = "d"
+_check_size(c_double)
if _calcsize("l") == _calcsize("q"):
# if long and long long have the same size, make c_longlong an alias for c_long
@@ -177,33 +198,40 @@ if _calcsize("l") == _calcsize("q"):
else:
class c_longlong(_SimpleCData):
_type_ = "q"
+ _check_size(c_longlong)
class c_ulonglong(_SimpleCData):
_type_ = "Q"
## def from_param(cls, val):
## return ('d', float(val), val)
## from_param = classmethod(from_param)
+ _check_size(c_ulonglong)
class c_ubyte(_SimpleCData):
_type_ = "B"
c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
# backward compatibility:
##c_uchar = c_ubyte
+_check_size(c_ubyte)
class c_byte(_SimpleCData):
_type_ = "b"
c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
+_check_size(c_byte)
class c_char(_SimpleCData):
_type_ = "c"
c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
+_check_size(c_char)
class c_char_p(_SimpleCData):
_type_ = "z"
+_check_size(c_char_p, "P")
class c_void_p(_SimpleCData):
_type_ = "P"
c_voidp = c_void_p # backwards compatibility (to a bug)
+_check_size(c_void_p)
# This cache maps types to pointers to them.
_pointer_type_cache = {}