How do I build a python string from a ctype struct?

后端 未结 2 846
不知归路
不知归路 2021-02-06 13:35

I\'m using ctypes and I\'ve defined this struct in order to pass parameters

class my_struct(ctypes.Structure):
    _fields_ = [ (\"buffer\", ctypes.c_char * BUFS         


        
相关标签:
2条回答
  • 2021-02-06 13:57

    Your problem is that ctypes tries to do some magic for you with char arrays, auto-converting them into NUL-terminated strings. You can get around this magic by using the ctypes.c_byte type instead of ctypes.c_char and retrieving the value as a string with ctypes.string_at. You can make accessing the member a little nicer with a helper property on the structure class, such as:

    import ctypes
    BUFSIZE = 1024
    
    class my_struct(ctypes.Structure):
        _fields_ = [ ("_buffer", ctypes.c_byte * BUFSIZE),
                     ("size", ctypes.c_int )]
    
        def buffer():
            def fget(self):
                return ctypes.string_at(self._buffer, self.size)
            def fset(self, value):
                size = len(value)
                if size > BUFSIZE:
                    raise ValueError("value %s too large for buffer",
                                     repr(value))
                self.size = size
                ctypes.memmove(self._buffer, value, size)
            return property(fget, fset)
        buffer = buffer()
    
    proto = my_struct()
    proto.buffer = "here\0are\0some\0NULs"
    print proto.buffer.replace("\0", " ")
    
    0 讨论(0)
  • 2021-02-06 14:01

    I think you need to send a pointer to a C string in your my_struct, and not a C string directly, because C strings are null-terminated. Try to do it like this:

    import ctypes
    
    BUFSIZE = 10
    
    class my_struct(ctypes.Structure):
        _fields_ = [ ("buffer", ctypes.POINTER(ctypes.c_char)),
                     ("size", ctypes.c_int )]
    
    cstr = (ctypes.c_char * BUFSIZE)()
    proto = my_struct(cstr)
    
    0 讨论(0)
提交回复
热议问题