简体   繁体   中英

Python ctypes union, string, str, byte: three Pythons, three different results

A colleague was asked to provide a starting point for socket client and server applications that I could adapt to our customer's needs. He provided something a lot fancier than I expected, and provided an excellent lesson in Python programming for me.

But he targeted his programs to Python 2.7. I have spent my entire time at this company trying to drag it into the 20th century. (Note that I didn't say 21st.) I want to use Python 3.2 (not 3.5 because everybody but me uses PythonWin, which won't work with 3.5. I use PyCharm).

The code supplied by my colleague uses the ctypes module's Structure and Union classes. In Python 3.2, the first line of the __init__ method throws this exception: TypeError: expected string, str found. In Python 3.5, the error is "TypeError: expected bytes, str found." In Python 2.7, there is no error and the code works.

This is my first encounter with the ctypes module, and I only met Python 3 when I began this project. Can someone tell me what I need to do to get this to work?

Here's the code:

class AliveMsg(Structure):
    """
    """
    _pack_ = 1
    _fields_ = [("Header", MsgHeader),  # Header
                ("EndFlag", c_char * 1)]  # End Flag always '#'


class TransAlive(Union):
    length = 49

    _pack_ = 1
    _fields_ = [("Struct", AliveMsg),
                ("Message", c_char * 49),
                ("Initialize", c_char * 49)]

    def __init__(self):
        self.Initialize = ' ' * 49
        self.Struct.Header.START_FLAG = '*'
        self.Struct.Header.SEP1 = ';'
        self.Struct.Header.SEP2 = ';'
        self.Struct.Header.SEP3 = ';'
        self.Struct.Header.SEP4 = ';'
        self.Struct.Header.HEADER_END = 'Data:'
        self.Struct.EndFlag = '#'

Use byte strings instead of Unicode strings for c_char . Unicode strings are the default in Python 3, but byte strings are the default in Python 2. For example:

self.Initialize = b' ' * 49

If you assign text to Message , to use non-ASCII you can use a Unicode string but encode it to a byte string in an appropriate encoding:

self.Message = 'Some Chinese: 马克'.encode('utf8')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM