2013-10-17 17 views
0

我在Python 2.7中第一次使用ctypes有点麻烦。问题如下:将结构传递给本地库与ctypes的问题

  1. 我在本地代码中调用一个函数来给我一些内存。该函数给了我一个指向缓冲区的指针。在继续之前,缓冲区被转换为ctypes结构体。
  2. 我分配了一些结构成员,并执行一个memmove来填充我需要的字段。
  3. 指向缓冲区的指针被传递给库中的另一个函数。

问题是,其他函数没有看到我在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; 

在此先感谢您的帮助!

+0

在'memmove'之后和发送数据包之前,您能否确认新的副本? – abstractpaper

+0

数据按预期呈现。例如,pxCspPacket.contents.length产生一个我期望的值,以及pxCspPacket.contents.data的内容。 – MaXim

回答

1

我发现了这个问题,这与我使用ctypes的方式没有关系。事实证明,C中struct的定义与我的python绑定有所不同 - CSP_PADDING_BYTES在本地库中被定义为8个字节,而Python绑定中的填充被设置为46个字节。

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

+1

那么,这是解决方案还是还存在问题?如果没有,您可以将自己的答案标记为此问题的答案。 – Albert