Protocol Buffer技术深入理解技术深入理解(C++实例实例)
C++实例Protocol Buffer技术详解,感兴趣的朋友可以了解下
这篇Blog仍然是以Google的官方文档为主线,代码实例则完全取自于我们正在开发的一个Demo项目,通过前一段时间的尝
试,感觉这种结合的方式比较有利于培训和内部的技术交流。还是那句话,没有最好的,只有最适合的。我想写Blog也是这一
道理吧,不同的技术主题可能需要采用不同的风格。好了,还是让我们尽早切入主题吧。
一、生成目标语言代码一、生成目标语言代码
下面的命令帮助我们将MyMessage.proto文件中定义的一组Protocol Buffer格式的消息编译成目标语言(C++)的代码。至于消
息的内容,我们会在后面以分段的形式逐一列出,同时也会在附件中给出所有源代码。
复制代码 代码如下:
protoc -I=./message --cpp_out=./src ./MyMessage.proto
从上面的命令行参数中可以看出,待编译的文件为MyMessage.proto,他存放在当前目录的message子目录下。--cpp_out参数
则指示编译工具我们需要生成目标语言是C++,输出目录是当前目录的src子目录。在本例中,生成的目标代码文件名是
MyMessage.pb.h和MyMessage.pb.cc。
二、简单二、简单message生成的生成的C++代码代码
这里先定义一个最简单的message,其中只是包含原始类型的字段。
复制代码 代码如下:
option optimize_for = LITE_RUNTIME;
message LogonReqMessage {
required int64 acctID = 1;
required string passwd = 2;
}
由于我们在MyMessage文件中定义选项optimize_for的值为LITE_RUNTIME,因此由该.proto文件生成的所有C++类的父类均
为::google::protobuf::MessageLite,而非::google::protobuf::Message。在上一篇博客中已经给出了一些简要的说
明,MessageLite类是Message的父类,在MessageLite中将缺少Protocol Buffer对反射的支持,而此类功能均在Message类中
提供了具体的实现。对于我们的项目而言,整个系统相对比较封闭,不会和更多的外部程序进行交互,与此同时,我们的客户
端部分又是运行在Android平台,有鉴于此,我们考虑使用LITE版本的Protocol Buffer。这样不仅可以得到更高编码效率,而且
生成代码编译后所占用的资源也会更少,至于反射所能带来的灵活性和极易扩展性,对于该项目而言完全可以忽略。下面我们
来看一下由message LogonReqMessage生成的C++类的部分声明,以及常用方法的说明性注释。
复制代码 代码如下:
class LogonReqMessage : public ::google::protobuf::MessageLite {
public:
LogonReqMessage();
virtual ~LogonReqMessage();
// implements Message ----------------------------------------------
//下面的成员函数均实现自MessageLite中的虚函数。
//创建一个新的LogonReqMessage对象,等同于clone。
LogonReqMessage* New() const;
//用另外一个LogonReqMessage对象初始化当前对象,等同于赋值操作符重载(operator=)
void CopyFrom(const LogonReqMessage& from);
//清空当前对象中的所有数据,既将所有成员变量置为未初始化状态。
void Clear();
//判断当前状态是否已经初始化。
bool IsInitialized() const;
//在给当前对象的所有变量赋值之后,获取该对象序列化后所需要的字节数。
int ByteSize() const;
//获取当前对象的类型名称。
::std::string GetTypeName() const;
// required int64 acctID = 1;
//下面的成员函数都是因message中定义的acctID字段而生成。
//这个静态成员表示AcctID的标签值。命名规则是k + FieldName(驼峰规则) + FieldNumber。
static const int kAcctIDFieldNumber = 1;
//如果acctID字段已经被设置返回true,否则false。
inline bool has_acctid() const;
//执行该函数后has_acctid函数将返回false,而下面的acctid函数则返回acctID的缺省值。
inline void clear_acctid();
//返回acctid字段的当前值,如果没有设置则返回int64类型的缺省值。
inline ::google::protobuf::int64 acctid() const;
//为acctid字段设置新值,调用该函数后has_acctid函数将返回true。
inline void set_acctid(::google::protobuf::int64 value);