On 02-Oct-16 19:50, Michael Felt wrote:
class perfstat_cpu_total_t(Structure):
    """
typedef struct { /* global cpu information */
int ncpus; /* number of active logical processors */
        int ncpus_cfg;             /* number of configured processors */
char description[IDENTIFIER_LENGTH]; /* processor description (type/official name) */ u_longlong_t buffer1[15]; /* several variables being skipped for now */ time_t lbolt; /* number of ticks since last reboot */ u_longlong_t loadavg[3]; /* (1<<SBITS) times the average number of runnables processes during the last
 1, 5 and 15 minutes.    */
u_longlong_t buffer2[29]; /* several variables being skipped for now */
        int ncpus_high;           /* index of highest processor online */
u_longlong_t puser; /* raw number of physical processor tics in user mode */ u_longlong_t psys; /* raw number of physical processor tics in system mode */ u_longlong_t pidle; /* raw number of physical processor tics idle */ u_longlong_t pwait; /* raw number of physical processor tics waiting for I/O */ u_longlong_t buffer2[29]; /* several variables being skipped for now */
} perfstat_cpu_total_t;
"""
_fields_ = [
     ("ncpus", c_int),
     ("ncpus_cfg", c_int),
     ("description", c_char * IDENTIFIER_LENGTH),
     ("buffer1", c_ulonglong * 15),
     ("lbolt", time_t),
     ("loadavg", c_ulonglong * 3),
     ("buffer2", c_ulonglong * 29),
     ("ncpus_high", c_int),
     ("puser", c_ulonglong),
     ("psys", c_ulonglong),
     ("pidle", c_ulonglong),
     ("pwait", c_ulonglong),
     ("buffer3", c_ulonglong * 12)
    ]
Perhaps I should explain what I want to accomplish.

a) use ctypes.CDLL to open libperfstat.a(shr_64.o)
b) call a number for functions, among them

The prototype template (in C) is:

The common signature used by all of the global interfaces is as follows:
int perfstat_subsystem_total(
   perfstat_id_t *name,
   perfstat_subsystem_total_t *userbuff,
   int sizeof_struct,
   int desired_number);

The usage of the parameters for all of the interfaces is as follows:
  perfstat_id_t *name Reserved for future use, should be NULL
perfstat_subsystem_total_t *userbuff A pointer to a memory area with enough space for the returned structure
  int sizeof_struct Should be set to sizeof(perfstat_subsystem_t)
  int desired_number Reserved for future use, must be set to 0 or 1

The return value will be -1 in case of errors. Otherwise, the number of structures copied is returned. This
is always 1.

So, in C the call looks something like this - for cpu_total

perfstat_cpu_total(NULL, (struct perfstat_cpu_total_t *) &xxx, 
sizeof(perfstat_cpu_total_t), 1)

I am struggling with the declarations needed to make the call

I have several iterations - the most simple case (no CFUNCTYPE declaration) 
gives

   +79  class cpu_total:
   +80      def __init__(self):
   +81          __perfstat__ = CDLL("libperfstat.a(shr_64.o)")
   +82          xxx = perfstat_cpu_total_t
   +83          cpu_total = __perfstat__.perfstat_cpu_total
   +84          ret = cpu_total(None, xxx, sizeof(xxx), 1)
   +85          print xxx.ncpus
   +86          print xxx.lbolt.v
   +87
   +88  a = cpu_total()

!cat test_1.py | python
Traceback (most recent call last):
  File "<stdin>", line 88, in <module>
  File "<stdin>", line 84, in __init__
ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: Don't know how 
to convert parameter 2

I have tried some experiments with CFUNCTYPE - basically

 prototype = CFUNCTYPE(c_int, c_void_p, c_int, c_int, c_int)

but I do not understand how (I think some of the details are missing from the 
example) how the following works:

I have also tried:

   +80      def __init__(self):
   +81          __perfstat__ = CDLL("libperfstat.a(shr_64.o)")
   +82          xxx = perfstat_cpu_total_t
   +83          xptr = POINTER(xxx)
   +84          x2 = cast(xptr,POINTER(c_void_p))
   +85          cpu_total = __perfstat__.perfstat_cpu_total
   +86          ret = cpu_total(None, x2, sizeof(xxx), 1)
   +87          print xxx.ncpus
   +88          print xxx.lbolt.v
   +89
   +90  a = cpu_total()
   +91  print sizeof(a)
!cat test_1.py | python
Traceback (most recent call last):
  File "<stdin>", line 90, in <module>
  File "<stdin>", line 84, in __init__
  File "/opt/lib/python2.7/ctypes/__init__.py", line 509, in cast
    return _cast(obj, obj, typ)
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: wrong type

   +79  class cpu_total:
   +80      def __init__(self):
   +81          __perfstat__ = CDLL("libperfstat.a(shr_64.o)")
   +82          xxx = perfstat_cpu_total_t
   +83          xptr = POINTER(xxx)
   +84          cpu_total = __perfstat__.perfstat_cpu_total
   +85          ret = cpu_total(None, xptr, sizeof(xxx), 1)
   +86          print xxx.ncpus
   +87          print xxx.lbolt.v
   +88
   +89  a = cpu_total()
   +90  print sizeof(a)
   +91
!cat test_1.py | python
Traceback (most recent call last):
  File "<stdin>", line 89, in <module>
  File "<stdin>", line 85, in __init__
ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: Don't know how 
to convert parameter 2

and

   +79  class cpu_total:
   +80      def __init__(self):
   +81          __perfstat__ = CDLL("libperfstat.a(shr_64.o)")
   +82          xxx = perfstat_cpu_total_t
   +83          xptr = c_void_p(xxx)
   +84          cpu_total = __perfstat__.perfstat_cpu_total
   +85          ret = cpu_total(None, xptr, sizeof(xxx), 1)
   +86          print xxx.ncpus
   +87          print xxx.lbolt.v
   +88
   +89  a = cpu_total()
   +90  print sizeof(a)
   +91
!cat test_1.py | python
Traceback (most recent call last):
  File "<stdin>", line 89, in <module>
  File "<stdin>", line 83, in __init__
TypeError: cannot be converted to pointer



I know they are "stabs in the dark" as I really do not grasp the documentation. 
Maybe it is clear to someone well versed in python, or just smarter than I.

Your expert assistance is appreciated!






--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to