Structures and unions must derive from the Structure and Union
base classes which are defined in the ctypes
module. Each subclass
must define a _fields_ attribute. _fields_ must be a list of
2-tuples, containing a field name and a field type.
The field type must be a ctypes
type like c_int, or any other
derived ctypes
type: structure, union, array, pointer.
Here is a simple example of a POINT structure, which contains two
integers named x
and y
, and also shows how to initialize a
structure in the constructor:
>>> from ctypes import * >>> class POINT(Structure): ... _fields_ = [("x", c_int), ... ("y", c_int)] ... >>> point = POINT(10, 20) >>> print point.x, point.y 10 20 >>> point = POINT(y=5) >>> print point.x, point.y 0 5 >>> POINT(1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: too many initializers >>>
You can, however, build much more complicated structures. Structures can itself contain other structures by using a structure as a field type.
Here is a RECT structure which contains two POINTs named upperleft
and lowerright
>>> class RECT(Structure): ... _fields_ = [("upperleft", POINT), ... ("lowerright", POINT)] ... >>> rc = RECT(point) >>> print rc.upperleft.x, rc.upperleft.y 0 5 >>> print rc.lowerright.x, rc.lowerright.y 0 0 >>>
Nested structures can also be initialized in the constructor in several ways:
>>> r = RECT(POINT(1, 2), POINT(3, 4)) >>> r = RECT((1, 2), (3, 4))
Fields descriptors can be retrieved from the class, they are useful for debugging because they can provide useful information:
>>> print POINT.x <Field type=c_long, ofs=0, size=4> >>> print POINT.y <Field type=c_long, ofs=4, size=4> >>>
See About this document... for information on suggesting changes.