[英]How to elegantly send/receive a large C struct using Python?
我已經開始編寫Python 3.x客戶端應用程序了。 服務器應用程序已經存在並且用C語言編寫。服務器提供了一個C頭文件,其中包含用於通過UDP發送和接收數據的兩種結構的定義(我正在使用Python的socket
模塊)。 問題是C結構非常大(每個大約200個元素)。 如果我使用Python的struct
模塊來打包/解包數據,那么一個不那么優雅的解決方案就是手動打包/解包200個元素,如:
struct.pack('H...I', data1, ..., data200)
此外,我希望能夠使用類似C的語法訪問Python中的接收/發送元素。 例如,如果我在C服務器端
send.data.pos = pos;
如果我可以像這樣訪問Python客戶端中的pos
變量,那將是很好的(最自然的):
pos = recv.data.pos
請注意,問題不在於如何從頭文件中自動編寫Python結構,就像在這個線程中一樣(我在Python中逐個編寫每個結構字段都沒有問題),而是最好的組織方式Python中的數據(例如,在類中,使用字典等),這將允許我利用Python功能,使代碼更簡單,數據易於訪問(我寧願只使用Python標准模塊,也不使用外部軟件)。 實現這一目標最優雅的方法是什么?
您可以編寫一個具有成員函數的類,使用struct.pack
等將數據打包/解包到類屬性中。
我建議看看Construct 。 但我認為它還沒有被移植到Python 3.x. 構造已經中斷了一段時間,但最近被新開發人員接受了,所以也許很快就可以支持Python 3.x.
試試這個 - 適用於2.7和3.2。
腳本:
import struct, collections
class CStruct(object):
def __init__(self, typename, format_defn, lead_char="!"):
self.names = []
fmts = [lead_char]
for line in format_defn.splitlines():
name, fmt = line.split()
self.names.append(name)
fmts.append(fmt)
self.formatstr = ''.join(fmts)
self.struct = struct.Struct(self.formatstr)
self.named_tuple_class = collections.namedtuple(typename, self.names)
def object_from_bytes(self, byte_str):
atuple = self.struct.unpack(byte_str)
return self.named_tuple_class._make(atuple)
if __name__ == "__main__":
# do this once
pkt_def = """\
u1 B
u2 H
u4 I"""
cs = CStruct("Packet1", pkt_def)
# do this once per incoming packet
o = cs.object_from_bytes(b"\xF1\x00\xF2\x00\x00\x00\xF4")
print(o)
print(o.u4)
輸出:
Packet1(u1=241, u2=242, u4=244)
244
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.