我正在尝试序列化下面的C结构
struct packet
{
int id;
unsigned char *ce;
unsigned char *syms;
};
然后通过socket发送。ce
和syms
所指向的元素的数量已知为N
。目前我是这样做的。首先,我使用ctypes将结构体 Package 为
class Packet(Structure):
_fields_ = [("id", c_int),
("ce", POINTER(c_ubyte)),
("syms", POINTER(c_ubyte))]
然后,我使用ctypes.POINTER(Packet)
中的fill_data
函数填充以下类的对象:
class DataLoad:
def __init__(self):
self.id = -1
self.ce = []
self.syms = []
def fill_data(self, pkt_p):
""" pkt_p is POINTER(Packet)
"""
self.id = pkt_p.contents.id
self.ce = []
for i in range(N):
self.ce.append(pkt_p.contents.ce[i])
self.syms = []
for i in range(N):
self.syms.append(pkt_p.contents.syms[i])
最后,我简单地使用pickle.dumps(DataLoad)
生成一个字节流并发送。
这种方法效果很好。但是,它似乎相当缓慢。我可以看到的一个原因是pickle.dumps
带来了很多开销。例如,如果C结构体只有1024个字节,我可能必须使用pickle为每个结构体发送近4000个字节。此外,打包/填充DataLoad也需要时间。
所以我的问题是,我是否有其他更好的选择来用Python序列化这个C结构并发送?我更倾向于避免pickle并填充一个单独的类示例。谢谢。
3条答案
按热度按时间h4cxqtbf1#
最后,我想出了下面的方法来手动序列化“Packet”示例,而不使用pickle。
string_at()
和from_buffer_copy()
函数是关键。sr4lhrrt2#
首先,如果你知道元素的个数是N,我建议你把结构改成这样:
接下来,如果您只想发送结构数据,则不需要pickle整个数据。只需发送数据包数据:
读取另一端的数据:
yptwkmov3#
Packer是一个序列化和反序列化数据的存储库,适用于python和C。
https://github.com/souzomain/Packer