working with ctypes and complex data structures

Emile van Sebille emile at fenx.com
Wed Oct 5 16:29:38 EDT 2016


On 10/05/2016 01:06 PM, Michael Felt wrote:
>
>
> On 02-Oct-16 19:50, Michael Felt wrote:
>> I am trying to understand the documentation re: ctypes and interfacing
>> with existing libraries.
>>
>> I am reading the documentation, and also other sites that have largely
>> just copied the documentation - as well as the "free chapter" at
>> O'Reilly (Python Cookbook).
>>
> Using O'Reilly and the standard documentation I now have these two
> excerpts. The second def works, the first does not.
>
> Someone helping me understand what I am not reading properly in this bit
> of documentation - is much appreciated.
>
>>>> from  ctypes  import  c_int,  WINFUNCTYPE,  windll
>>>> from  ctypes.wintypes  import  HWND,  LPCSTR,  UINT
>>>> prototype  =  WINFUNCTYPE(c_int,  HWND,  LPCSTR,  LPCSTR,  UINT)
>>>> paramflags  =  (1,  "hwnd",  0),  (1,  "text",  "Hi"),  (1,
>>>> "caption",  None),  (1,  "flags",  0)
>>>> MessageBox  =  prototype(("MessageBoxA",  windll.user32),  paramflags)
>>>>
>
> The MessageBox foreign function can now be called in these ways:
>
>>>>
>
>>>> MessageBox()
>>>> MessageBox(text="Spam, spam, spam")
>>>> MessageBox(flags=2,  text="foo bar")
>>>>
>
> Note that MessageBox() may give two arguments.
>
> My code: note both def init() are meant to do the same thing, just
> different call syntax.
>
>    +76  class cpu_total:
>    +77      def __init__(self):
>    +78          __perfstat__ = CDLL("libperfstat.a(shr_64.o)")
>    +79          prototype = CFUNCTYPE(c_int, c_void_p, c_void_p, c_int,
> c_int)
>    +80          args = (1, "name", None), (2, "buff", None), (1, "size",
> 0), (1, "count", 1)
>    +81          cpu_total = prototype(("perfstat_cpu_total",
> __perfstat__), args)
>    +82
>    +83          buff = perfstat_cpu_total_t()
>    +84          cpu_total(buff=buff, size=sizeof(buff))
>    +85
>    +86  class perfstat_cpu_total:
>    +87      def __init__(self):
>    +88          __perfstat__ = CDLL("libperfstat.a(shr_64.o)")
>    +89          cpu_total = __perfstat__.perfstat_cpu_total
>    +90
>    +91          _perfstat_cpu_total = perfstat_cpu_total_t()
>    +92          ret = cpu_total(None,
>    +93                          byref(_perfstat_cpu_total),
>    +94                          sizeof(perfstat_cpu_total_t), 1)
>    +95          self.boot = _perfstat_cpu_total.lbolt.v / 100
>    +96          self.ncpus = _perfstat_cpu_total.ncpus
>    +97          self._v = _perfstat_cpu_total
>
>
> When I call the second I can print values and even call functions,
> reload the _v, etc..
>
> The first class fails with this message:
>
> a = cpu_total()
> Traceback (most recent call last):
>   File "<stdin>", line 135, in <module>
>   File "<stdin>", line 84, in __init__
> TypeError: call takes exactly 1 arguments (2 given)
>
> Thanks for your attention.

the line it's objecting to is:

 >    +84          cpu_total(buff=buff, size=sizeof(buff))

because the expectation is defined as:

 >    +77      def __init__(self):

HTH,

Emile




More information about the Python-list mailing list