使用ctypes将struct传递给本机库时遇到麻烦

时间:2013-10-17 06:20:48

标签: c++ python c struct ctypes

我在Python 2.7中第一次使用ctypes时遇到了一些麻烦。问题如下:

  1. 我在本机代码中调用一个函数来给我一些记忆。该函数给了我一个指向缓冲区的指针。在继续之前,缓冲区被强制转换为ctypes结构。
  2. 我指定了一些结构成员,并执行memmove来填充我需要的字段。
  3. 指向缓冲区的指针将传递给库中的另一个函数。
  4. 问题是,另一个函数没有看到我在Python中所做的任何更改。我在Python解释器上使用gdb确认了这一点。基本上,我执行的任何操作似乎都没有任何效果,我期望设置的字段为零或不包含任何数据。

    以下是与库交互的Python代码:

    pxCspPacket = ctypes.cast(                                  
            pycsp.csp_buffer_get(bytesToSend),          
            ctypes.POINTER(pycsp.csp_packet_t))
    
    pxCspPacket.contents.length = bytesToSend
    ctypes.memmove(pxCspPacket.contents.data,                   
            dataToSend,                                         
            bytesToSend)
    
    # Send packet
    pycsp.csp_send(conn, pxCspPacket, self.cspTimeout)
    

    对库的绑定如下:

    class csp_packet_t (ctypes.Structure):
            _pack_ = 1
            _fields_ = [("padding", ctypes.c_uint8 * 46),
                ("length", ctypes.c_uint16),
                ("id", csp_id_t),
                ("data", ctypes.c_uint8 * 256)]
    

    C中结构的相应定义:

    typedef struct __attribute__((__packed__)) {
            uint8_t padding[CSP_PADDING_BYTES]; 
            uint16_t length;
            csp_id_t id;
            union {
                    uint8_t data[0];
                    uint16_t data16[0];
                    uint32_t data32[0];
            };
    } csp_packet_t;
    

    提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

我发现了这个问题,这与我使用ctypes的方式无关。事实证明,C语言中结构的定义与我的python绑定不同 - CSP_PADDING_BYTES在本机库中定义为8个字节,而Python绑定中的填充设置为46个字节。

绑定和结构定义不是我自己的代码,但至少我知道如何解决它!