BYTE to python C-Type structure Conversion Issue
Question: I am facing a little problem on deserializing some bytes that have been
received from the POSIX Queue.

We are trying to develop a module where a Python application will post a POSIX
queue data to a C application and C will re-post data to Python Queue..

All data is Ctype Structure based.

Structure defintion:

**msgStruct.py**

    
    
    MAX_MSG_SIZE = 5120
    class MsgStruct(ctypes.Structure):
        _fields_ = [
                    ("msgType", ctypes.c_int),
                    ("msgSize",ctypes.c_int),
                    ("setState",ctypes.c_int),
                    ("msgBuf",ctypes.c_char * MAX_MSG_SIZE)
                ]
    

**conversions.py**

    
    
    class conversions():
        def serialize(ctypesObj):
            """
            FAQ: How do I copy bytes to Python from a ctypes.Structure?
            """
            return buffer(ctypesObj)[:]
    
        def deserialize(ctypesObj, inputBytes):
            """
            FAQ: How do I copy bytes to a ctypes.Structure from Python?
            """
            fit = min(len(inputBytes), ctypes.sizeof(ctypesObj))
            ctypes.memmove(ctypes.addressof(ctypesObj), inputBytes, fit)
            return ctypesObj    
    

**test.py**

    
    
    from mapStruct import *
    from conversions import conversions
    wrapper=conversions()
    data="\x01\x00\x00\x00\x70\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00\x25\x42\x35\x32\x33\x39\x35\x31\x32\x35\x32\x34\x38\x39\x35\x30\x30\x36\x5e\x56\x45\x4e\x4b\x41\x54\x20\x52\x41\x47\x41\x56\x41\x4e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5e\x31\x36\x30\x34\x31\x30\x31\x31\x36\x35\x35\x36\x30\x30\x31\x34\x31\x30\x30\x30\x30\x30\x30\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x35\x32\x33\x39\x35\x31\x32\x35\x32\x34\x38\x39\x35\x30\x30\x36\x3d\x31\x36\x30\x34\x31\x30\x31\x31\x34\x31\x30\x3f\x00\x00...\x00"
    """
    Data is the Queue data that is recieved by python
    """
    baseStruct=MsgStruct()
    rxData=wrapper.deserialize(baseStruct,data)
    print rxData.setState # Prints as expected
    print rxData.msgType # Prints as expected
    print rxData.msgSize
    print rxData.msgBuf.encode('hex') # here is probles i dont C any data in this buffer
    

Please guide me on solving this issue. I am very much surprised that the
buffer(rxData.msgSize) is always empty and would like to know why.


Answer: `ctypes` is trying to be helpful with `c_char` buffers by converting it into a
Python string. The conversion stops at the first null byte. Observe what
happens when I change the first couple bytes of data in your data buffer:

    
    
    0
    1
    368
    b'\x01\x02'
    

Change the type of `msgBuf` to `c_ubyte` instead so `ctypes` won't try to be
"helpful" and then look at the data character-by-character with:

    
    
    >>> print repr(''.join(chr(x) for x in rxData.msgBuf))
    '\x00\x00\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00%B5239512524 ...
    

But there is no reason to use `ctypes` at all:

    
    
    import struct
    
    data=b"\x01\x00\x00\x00\x70\x01\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00\x25\x42\x35\x32\x33\x39\x35\x31\x32\x35\x32\x34\x38\x39\x35\x30\x30\x36\x5e\x56\x45\x4e\x4b\x41\x54\x20\x52\x41\x47\x41\x56\x41\x4e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5e\x31\x36\x30\x34\x31\x30\x31\x31\x36\x35\x35\x36\x30\x30\x31\x34\x31\x30\x30\x30\x30\x30\x30\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x35\x32\x33\x39\x35\x31\x32\x35\x32\x34\x38\x39\x35\x30\x30\x36\x3d\x31\x36\x30\x34\x31\x30\x31\x31\x34\x31\x30\x3f\x00\x00...\x00"
    
    msg_offset = struct.calcsize('iii')
    print struct.unpack_from('iii',data)
    print repr(data[msg_offset:])
    

Output:

    
    
    (1, 368, 0)
    '\x01\x02\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00%B5239512524895006^VENKAT RAGAVAN            ^16041011655600141000000?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;5239512524895006=16041011410?\x00\x00...\x00'
    

