working with ctypes and complex data structures
Michael Felt
michael at felt.demon.nl
Thu Oct 6 06:15:07 EDT 2016
On 04-Oct-16 04:48, eryk sun wrote:
> On Mon, Oct 3, 2016 at 9:27 PM, Michael Felt <michael at felt.demon.nl> wrote:
>> int perfstat_subsystem_total(
>> perfstat_id_t *name,
>> perfstat_subsystem_total_t *userbuff,
>> int sizeof_struct,
>> int desired_number);
>> ...
>> +79 class cpu_total:
>> +80 def __init__(self):
>> +81 __perfstat__ = CDLL("libperfstat.a(shr_64.o)")
Thanks for the model below - a lot to think about. Some was expected,
some is a gift!
Python is "a lot to learn". This helps a great deal.
> Move loading the library and defining function prototypes to either
> the module or class body. Also, don't use dunder names. The convention
> for a private attribute is a single underscore. For type safety,
> define each function's argtypes (and restype where required, the
> default is c_int). For a more Pythonic interface, define a ctypes
> errcheck function that encapsulates raising an appropriate exception
> when a C call fails. For example:
>
> import ctypes
>
> # If the following types are used generally, define them at
> # the module level, else define them in the class namespace
> # that uses them.
>
> perfstat = ctypes.CDLL("libperfstat.a(shr_64.o)")
>
> class perfstat_id_t(ctypes.Structure):
> pass
>
> IDENTIFIER_LENGTH = 64
>
> class time64_t(ctypes._SimpleCData):
> _type_ = ctypes.c_int64._type_
>
> time_t = time64_t
>
> class perfstat_cpu_total_t(ctypes.Structure):
> _fields_ = (("ncpus", ctypes.c_int),
> ("ncpus_cfg", ctypes.c_int),
> ("description", ctypes.c_char * IDENTIFIER_LENGTH),
> ("buffer1", ctypes.c_ulonglong * 15),
> ("lbolt", time_t),
> ("loadavg", ctypes.c_ulonglong * 3),
> ("buffer2", ctypes.c_ulonglong * 29),
> ("ncpus_high", ctypes.c_int),
> ("puser", ctypes.c_ulonglong),
> ("psys", ctypes.c_ulonglong),
> ("pidle", ctypes.c_ulonglong),
> ("pwait", ctypes.c_ulonglong),
> ("buffer3", ctypes.c_ulonglong * 12))
>
> def _perfstat_errcheck(result, func, args):
> if result == -1:
> # get error info and
> raise SomeException()
> return args
>
> class CPUTotal(object):
> # These may be defined here or just referenced here.
> _perfstat = perfstat
> _perfstat_id_t = perfstat_id_t
> _perfstat_cpu_total_t = perfstat_cpu_total_t
>
> _cpu_total = _perfstat.perfstat_cpu_total
> _cpu_total.errcheck = _perfstat_errcheck
> _cpu_total.argtypes = (
> ctypes.POINTER(_perfstat_id_t),
> ctypes.POINTER(_perfstat_cpu_total_t),
> ctypes.c_int, ctypes.c_int)
>
> def __init__(self):
> self._tcpu = self._perfstat_cpu_total_t()
> self._cpu_total(None,
> ctypes.byref(self._tcpu),
> ctypes.sizeof(self._tcpu), 1)
More information about the Python-list
mailing list