centos7下实现protobuf转换

protobuf版本:2.5.0

编译见另一篇博文。

 

首先需要创建一个proto文件,定义我们所需处理的结构化数据,在pb中,结构化数据一般称为massage,如下所示:

package lm; 
message helloworld 
{ 
   required int32     id = 1;  // ID 
   required string    str = 2;  // str 
   optional int32     opt = 3;  //optional field 
}

表示创建一个名为helloworld的结构,id和str为required类型,表明必须包含该成员,第三个opt的类型是optional表明可选。

 

编译该文件:

protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/helloworld.proto

假设helloworld.proto文件粗存放在 $SRC_DIR下。

 

命令将生成两个文件:

lm.helloworld.pb.h , 定义了 C++ 类的头文件

lm.helloworld.pb.cc , C++ 类的实现文件

在生成的头文件中,定义了一个 C++ 类 helloworld,后面的 Writer 和 Reader 将使用这个类来对消息进行操作。诸如对消息的成员进行赋值,将消息序列化等等都有相应的方法。

 

第二步就是编写write和read文件,write用来转换为pb类型,read表示将pb转成普通类型。

 

如前所述,Writer 将把一个结构化数据写入磁盘,以便其他人来读取。假如我们不使用 Protobuf,其实也有许多的选择。一个可能的方法是将数据转换为字符串,然后将字符串写入磁盘。转换为字符串的方法可以使用 sprintf(),这非常简单。数字 123 可以变成字符串”123”。

这样做似乎没有什么不妥,但是仔细考虑一下就会发现,这样的做法对写 Reader 的那个人的要求比较高,Reader 的作者必须了 Writer 的细节。比如”123”可以是单个数字 123,但也可以是三个数字 1,2 和 3,等等。这么说来,我们还必须让 Writer 定义一种分隔符一样的字符,以便 Reader 可以正确读取。但分隔符也许还会引起其他的什么问题。最后我们发现一个简单的 Helloworld 也需要写许多处理消息格式的代码。

 

使用 Protobuf,Writer 的工作很简单,需要处理的结构化数据由 .proto 文件描述,经过上一节中的编译过程后,该数据化结构对应了一个 C++ 的类,并定义在 lm.helloworld.pb.h 中。对于本例,类名为 lm::helloworld。

 

write.cpp:

#include "lm.helloworld.pb.h"
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
 lm::helloworld msg1;
 msg1.set_id(101);
 msg1.set_str("hello");

 fstream output("./log", ios::out | ios::trunc | ios::binary);

 if (!msg1.SerializeToOstream(&output)) {
  cerr << "Failed to write msg." << endl;
  return -1;
 }

return 0;

}

 

编译命令:

g++ write.cpp lm.helloworld.pb.cc -o write -I /usr/local/protobuf-2.5.0/include/ -L /usr/local/protobuf-2.5.0/lib -lprotobuf

 

read.cpp:

#include "lm.helloworld.pb.h"
#include <iostream>
#include <fstream>

using namespace std;

 void ListMsg(const lm::helloworld & msg) {
  cout << msg.id() << endl;
  cout << msg.str() << endl;
 }

 int main(int argc, char* argv[]) {

  lm::helloworld msg1;

  {
    fstream input("./log", ios::in | ios::binary);
    if (!msg1.ParseFromIstream(&input)) {
      cerr << "Failed to parse address book." << endl;
      return -1;
    }
  }

  ListMsg(msg1);
 }

 

编译:

g++ read.cpp lm.helloworld.pb.cc -o read -I /usr/local/protobuf-2.5.0/include/ -L /usr/local/protobuf-2.5.0/lib -lprotobuf

 

然后先后运行write和read,可以发现read可以生成write序列化之前的内容。说明序列化和反序列化都成功了。

 

在运行write和read时可能报错:

/write: error while loading shared libraries: libprotobuf.so.8: cannot open shared object file: No such file or directory

 

解决如下:

export LD_LIBRARY_PATH=/usr/local/protobuf-2.5.0/lib

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值