谷歌Protobuf比以往任何时候都更加困惑我,我正在努力了解事情的运作方式。
如果我理解正确,请帮助我理解。 .proto 文件定义消息的定义, protoc 是编译器。数据以二进制文件( .pb )编译。正确?如果没有,请你帮我理解。我无法处理Google Protobuf文档。这很令人困惑。并且没有与Stack Overflow或其他博客一起运气。
重要,我无法修改定义逻辑的C ++代码。话虽如此,我想反序列化 filename.pb (二进制文件)并通过Python解析结果。这可能吗?
提前感谢您的帮助!!
答案 0 :(得分:3)
我不确定我是否回答你的问题,但我会给你一个例子。一旦有了Protocol_pb2.py,就可以使用protobuf python API(可能还有struct
)轻松解析消息。我不是protobuf的专家,但我至少解析了Mumble消息。现在,我不知道你是如何使用protobuf以及为什么,但这个例子展示了如何解析mumble消息(使用protobuf),并希望能给你一些见解。所以:
导入protoc创建的protobuf文件(您按我回答上一个问题的方式创建它)&结构:
import struct
import Mumble_pb2 as mumble_protobuf
mumble_protobuf模块将包含转换为Python格式的.proto文件中定义的不同消息。您可以将不同的消息类型保存为例如dict:
PACKET_TYPES = {
0: mumble_protobuf.Version,
1: mumble_protobuf.UDPTunnel,
2: mumble_protobuf.Authenticate,
...
我在这里跳过了一些东西,但是一旦收到数据包的二进制数据就可以解析它。我想每个应用程序都会以不同的方式执行操作,但是例如,mumble发送前缀为2个字节的protobuf消息,其中包含消息类型,以及4个字节,用于指示数据包长度。这可能在您的应用程序中有所不同。无论如何,你必须知道你要解析什么样的消息(假设你的协议有多种消息类型)。但作为一个例子:
# The header format corresponds to the mumble packet that send the prefix + protobuf-msg
HEADER_FORMAT = ">HI" # Big endian, unsigned short + unsigned int
packet_type, packet_length = struct.unpack_from(HEADER_FORMAT, buffer)
如果缓冲区中有多条消息,则需要根据数据包长度从缓冲区中提取数据包数据。当您知道消息类型时,您可以解析它。这部分只是从pb2文件中获取与消息类型对应的类,并根据它解析消息。
MessageClass = PACKET_TYPES[packet_type]
message = MessageClass()
message.ParseFromString(packet_data)
现在message
最终将包含已解析的protobuf消息,您可以像构建它时一样使用它:您可以引用字段等:message.UserName
或其他。
答案 1 :(得分:-2)
是的,您可以使用protoc
生成的python代码对protobuf消息进行反序列化。 protoc编译器将以您的目标语言输出代码(在您的情况下为python
和C++
)。
以下是一些可以提供帮助的资源: