Trevor
Trevor

Reputation: 1663

how to cast multiple integers as a ctypes array of c_ubyte in Python

How does one convert a string of colon-separated hexadecimal numbers into a ctypes array of c_ubyte? According to the ctypes docs, I can cast a hard-coded collection, like so:

>>> from ctypes import *
>>> x = (c_ubyte * 6) (1, 2, 3, 4, 5, 6)
>>> x
<__main__.c_ubyte_Array_6 object at 0x480c5348>

Or, like so:

>>> XObj = c_ubyte * 6
>>> x = XObj(1, 2, 3, 4, 5, 6)
>>> x
<__main__.c_ubyte_Array_6 object at 0x480c53a0>

However, I cannot figure how to cast a variable list, like one generated from splitting a string, for example:

>>> mac = 'aa:bb:cc:dd:ee:ff'
>>> j = tuple(int(z,16) for z in mac.split(':'))
>>> j
(170, 187, 204, 221, 238, 255)
>>> x = (c_ubyte * 6) (j)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: an integer is required
>>> XObj = c_ubyte * 6
>>> x = XObj(j)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: an integer is required

What am I missing?

Thanks!

Upvotes: 2

Views: 3053

Answers (1)

Rostyslav Dzinko
Rostyslav Dzinko

Reputation: 40755

The problem is that in the first example you provided, you've used ctypes correctly by giving 6 arguments to XObj call, and in the second example (with mac address), you try to call the same object c_ubyte * 6, giving it a tuple, but not 6 values, so convert it using *args notation:

from c_types import c_ubyte

mac = 'aa:bb:cc:dd:ee:ff'
j = tuple(int(z,16) for z in mac.split(':'))

converted = (c_ubyte * 6)(*j)  # *j here is the most signigicant part
print converted

And the result is:

<__main__.c_ubyte_Array_6 object at 0x018BD300>

as expected.

Upvotes: 4

Related Questions