每天,我处理 定制软件开发 并参与各个行业的项目。我专注于 在嵌入式系统中使用 Modern C 以及使用 Qt 构建应用程序。在这里,我将与您分享我在 内存受限的嵌入式系统上需要协议缓冲区的项目中的经验。让我们来看看!
想象这样一种情况,几个人见面,每个人都说不同的语言。为了相互理解,他们开始使用团队中每个人都能理解的语言。然后,每个人想要说些什么都必须将他们的想法(通常是他们的母语)翻译成小组的语言。
然后我们可以说他们每个人都在群体的语言和特定的母语之间执行某种形式的编码和解码信息。
如果我们将单个语言更改为编程语言,将组语言更改为 Protocol Buffers 消息语言,我们将获得 Protocol Buffers 的优势之一;也就是说,能够以整个组都知道的特定编程语言创建消息,并将其翻译成只有特定组成员知道的语言的形式。
除了独立于语言和平台以及编码和解码数据的能力之外,Protocol Buffers 还可以快速有效地完成它。
根据 Wikipedia的说法,“Google 广泛使用协议缓冲区来存储和交换各种结构化信息。该方法作为自定义远程过程调用(RPC 或远程过程调用)系统的基础,该系统用于几乎所有的交互谷歌的机器通信。”
协议缓冲区徽标
协议缓冲区消息语言正如 Google 所说, “协议缓冲区使您能够定义一次数据的结构化方式(以 .proto 文件的形式),然后您可以使用特殊生成的源代码轻松编写和读取结构化数据往返于各种数据流并使用各种语言。”
协议缓冲区背后的想法
Protocol Buffers 语言指南继续说:“首先,让我们看一个非常简单的示例。假设您要定义一种Person消息格式,其中每个人都有姓名、年龄和电子邮件。这是.proto用于定义此消息类型的文件:
原始缓冲区
// person.proto
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
string email = 3;
}
该文件的第一行指定您正在使用proto3语法。”
Person消息定义指定了三个字段(名称/值对),每个字段用于您希望包含在此类消息中的每条数据。该字段具有 a name、 atype,和 a field number。
拥有.proto文件后,您可以生成特定语言的源代码:例如,C ,使用称为protocol compiler.aka的特殊编译器protoc。
协议编译器使用可视化
生成的文件包含语言原生结构来操作消息 Let's call it API。
API为您提供所有必要的类和方法set以及retrieve数据以及serialization to字节parsing from流的方法。序列化和解析是在后台处理的。
对于 C ,生成的文件包含Person类和所有必要的方法来处理底层数据。例如:
C
void clear_name();
const ::std::string &name() const;
void set_name(const ::std::string &value);
void set_name(const char *value);
此外,Person类继承方法从google::protobuf::Message流中序列化或反序列化(解析):
C
// Serialization:
bool SerializeToOstream(std::ostream* output) const;
bool SerializePartialToOstream(std::ostream* output) const;
// Deserialization:
bool ParseFromIstream(std::istream* input);
bool ParsePartialFromIstream(std::istream* input);
在 Protobuf-C 中使用自定义分配器进行静态分配
如果您正在编写一个完全静态分配的系统,那么您可能使用的是 C 而不是 C 。在这里,您将了解如何编写使用静态分配的缓冲区而不是动态分配的内存的自定义分配器。
背后的想法默认情况下Protobuf-C,解包时通过调用动态分配内存malloc()。有时它是no-go某些嵌入式系统或资源受限系统中的一个选项。
Protobuf-C使您能够提供custom allocator- 替代 malloc() 和 free() 函数 - 在本例中,serial_alloc().