Re: Strings with null characters

Mads Kiilerich <[email protected]> Sun, 26 Jun 2011 23:57:07 +0200
Newsgroups gmane.comp.python.ctypes
Message-ID <[email protected]>
Dominik George wrote, On 06/26/2011 04:10 PM:
> Hi,
>
> here is an example code that breaks:
>
> from ctypes import *
> class a(Structure):
>    _fields_ = [("aaa", c_char * 14)]
>
> mya = a()
> mya.aaa = "a\0b"
> print mya.aaa
> 'a'
>
>
> I found two workarounds at
> http://stackoverflow.com/questions/5082753/how-do-i-build-a-python-string-from-a-ctype-struct
> , but those solutions look somehow nasty ...

ctypes handles string-like struct fields in a special friendly way that 
often isn't very useful. Char arrays can normally be accessed 
zero-terminated through .value or directly through .raw - but not when 
they are used as struct members. That is a nasty problem that 
unfortunately requires a nasty solution.

One way to work around the issue is to avoid char arrays in structs and 
use byte arrays instead - and cast them to char arrays on demand as 
shown by this example:

from ctypes import *
class a(Structure):
   _fields_ = [("x", c_char), ("aaa", c_byte * 14)]
def chars(x):
   return cast(addressof(x), POINTER(c_char * sizeof(x))).contents
def dump(x):
   print repr(chars(x).raw)
mya = a()
dump(mya)
chars(mya.aaa).raw = "a\0b"
dump(mya)

or to make it a bit more like the stackoverflow example:

class a(Structure):
   _fields_ = [("x", c_char), ("_aaa", c_byte * 14)]
   @property
   def aaa(self):
     return chars(self._aaa)
mya = a()
mya.aaa.raw = "a\0b"

/Mads

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2