Dmitry
Dmitry

Reputation: 337

Why ctypes sizeof treats c_ubyte*1 and c_char*1 in the structure differently?

When I define a ctypes structure with c_char array as a field I can't get the size of that field, but if I switch to c_ubyte array I can. My understanding is that in the following example Python treats bar2 as a pointer (char*), but not bar1. I'd appreciate if someone can explain the logic behind that.

import ctypes
class Foo(ctypes.Structure):
    _fields_ = [ ('bar1', ctypes.c_ubyte*1),
                 ('bar2', ctypes.c_char*1) ]
foo = Foo()
for f,t in foo._fields_:
    print t

print ctypes.sizeof(foo.bar1)
print ctypes.sizeof(foo.bar2)

and this is the output:

<class '__main__.c_ubyte_Array_1'>
<class '__main__.c_char_Array_1'>
1
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print ctypes.sizeof(foo.bar2)
TypeError: this type has no size

Upvotes: 2

Views: 2427

Answers (1)

Armin Rigo
Armin Rigo

Reputation: 12945

foo.bar1 is indeed a ctypes array of 1 ubyte, but foo.bar2 is a string made out of what is in the array, considered as a null-terminated C string. It's clearer if you make longer arrays, say of length 5: if they contain for example the character 'A' repeated, then foo.bar1 will read as

<__main__.c_ubyte_Array_5 object at 0xf7551df4>

whereas foo.bar2 will read as

"AAAAA"

which is a normal Python string. This is a special case for the c_char type. Indeed, it's annoying because there is no clean way to write this value "AAAAA" into bar2 in the first place...

Upvotes: 3

Related Questions