简述
在上一篇 如何编译安装 protocolBuffer(for C++) 文章中讲述了如何编译,今天讲述一下如何使用,以及编译生成的一些选项以及额外的一些介绍。
1、新建.proto文件
下面我们先写一个简单的protobuf文件。
新建一个以.proto结尾的文件,如message.proto。然后添加一个Student结构。
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
message LoginReqMessage {
required int64 acctID = 1;
required string passwd = 2;
}
2、编译.proto文件
我们编译安装完protocolBuffer之后,会生成下面几个文件夹,bin目录下面就是protocolBuffer编译器了。
下面使用protoc命令对我们定义的message.proto文件进行编译。(前提需要将protoc.exe添加到环境变量Path中)
// $SRC_DIR 表示.proto文件所在目录;
// cpp_out 表示当前用于C++语言;
// $DST_DIR 表示编译生成文件的路径;
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/message.proto
这里我将message.proto文件放到D盘的protobuf文件夹下,然后编译生成目录为D盘的protobufFiles文件夹,执行以下命令。然后我们在protobufFiles文件夹下看到生成了message.pb.h和message.pb.cc文件。
这里需要注意两点,上文中我们在.proto文件的头部添加了以下两行代码,到底什么意思的,下面给出具体的解释说明。
syntax = “proto2”;
option optimize_for = LITE_RUNTIME;
注意一 : syntax = “proto2”;
如果不加第一行,在编译的时候会报错,见下图。
报错的原因就是我们没有指定protobuf的版本,所以这里需要指定一下当前使用protobuf的版本,我们当前使用proto2,注意proto3与proto2有一定的区别,如果这里用了proto3,那么就会报错,因为proto3中去掉了一些复杂的语法和特性,相比 proto2 支持更多语言而且更简洁,比如上面我们用到的required 字段在proto3中已经去掉了,所以这里编译失败。(具体proto3与proto2的区别这里就不具体阐述,感兴趣的小伙伴可以移至百度一下)
注意二: option optimize_for = LITE_RUNTIME;
上面可以看到我们新建的.proto文件加了下面一句,这一行到底是什么意思,可以看一下官网的解释。
option optimize_for = LITE_RUNTIME;
optimize_for即编译生成代码优化选项,Protocol Buffer定义三种优化级别SPEED / CODE_SIZE / LITE_RUNTIME。默认情况下是 SPEED 。而且这里提到了只会影响C++、Java以及一些第三方的代码生成。
SPEED: 生成的代码经过了很好的优化,所以运行效率高,但是由此编译生成的.h和.cc文件会占用更多的空间。
CODE_SIZE: 和SPEED恰恰相反,虽然代码运行效率较低,但是由此编译生成的代码占用的空间更少,通常用于资源有限的平台,如开发手机app。
LITE_RUNTIME: 生成的代码执行效率高,同时编译生成的代码所占用的空间也是非常少。但是省去了Protocol Buffer提供的反射功能,也算是小小的牺牲。所以我们在C++中链接Protocol Buffer库时仅需链接libprotobuf-lite.lib(占用空间较小,仅几兆),而不是libprotobuf.lib(占用空间较大,一百多兆)。
同时如果我们选择了LITE_RUNTIME选项,那么生成的代码中所有的类均将继承自MessageLite,而非Message,具体我们可以到源码中看一下 Message 和 MessageLite 类的区别。
同时对于以上三种选项,我这里做了测试,虽然只相差了几k,因为我这里只定义了LoginReqMessage 一个结构,如果存在大量的结构,那么生成的文件所占用的空间还是有很大差距的。所以需要根据不同的情况进行选择。
SPEED
message.pb.h 10k
message.pb.cc 19k
CODE_SIZE
message.pb.h 9k
message.pb.cc 11k
LITE_RUNTIME
message.pb.h 9k
message.pb.cc 14k
这里我们也可以看一下不同选项下生成的message.pb.h小小的区别(更多不同可以用BCompare对比)。
SPEED 和 CODE_SIZE 选项都继承了 Message类。
LITE_RUNTIME选项继承了 MessageLite类。
3、开始使用 protobuf
1、准备工作
将上一篇文章中编译打包好的include文件夹以及lib文件夹拷贝到当前项目下的protocolBuf文件夹。
然后将上面编译生成好的 message.pb.h和message.pb.cc放到src文件夹下,
2、为工程项目进行配置
添加包含目录。
添加库目录。
添加库。
添加编译之后protobuf文件。
3、编写代码
{
LogonReqMessage loginReq;
// 这里提供set方法进行设置;
loginReq.set_acctid(2017);
loginReq.set_passwd("Pig_XXX");
// 使用protobuf进行序列化;
std::string strMessage;
loginReq.SerializeToString(&strMessage);
// 使用protobuf进行反序列化;
LogonReqMessage loginReqTmp;
loginReqTmp.ParseFromString(strMessage);
// 获取结果;
int id = loginReqTmp.acctid();
std::string psw = loginReqTmp.passwd();
qDebug() << "Account : " << id << "Password : " << QString::fromStdString(psw);
}