protobuf学习

参考了这篇文章:

http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/

 

开发环境在我的线下开发机器的

/home/work/data/code/protobuf_demo

 

用jumbo安装的protobuf,安装目录在/home/work/.jumbo/

安装命令

jumbo search protobuf
jumbo install protobuf

装好后,写一个proto文件,放在/home/work/data/code/protobuf_demo/src/proto/messageName.proto 

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

用命令

protoc -I=proto --cpp_out=src proto/messageName.proto 

然后在src里面,写writer.cc文件

#include "messageName.pb.h"
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>

using namespace std;

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

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

return 0; }

编译命令:

export LD_LIBRARY_PATH=/home/work/.jumbo/lib/:$LD_LIBRARY_PATH
/opt/compiler/gcc-4.8.2/bin/g++ -o writer writer.cc messageName.pb.cc -L/home/work/.jumbo/lib/ -lprotobuf -I/home/work/.jumbo/include/

运行 ./writer之后,生成 ./log,内容:ehello

再写reader.cc文件:

#include "messageName.pb.h"
#include <fstream>
#include <iostream>

using namespace std;

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

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

  lm::helloworld msg;

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

  dumpMsg(msg);
}

编译命令(加上writer的)

export LD_LIBRARY_PATH=/home/work/.jumbo/lib/:$LD_LIBRARY_PATH
/opt/compiler/gcc-4.8.2/bin/g++ -o writer writer.cc messageName.pb.cc -L/home/work/.jumbo/lib/ -lprotobuf -I/home/work/.jumbo/include/
/opt/compiler/gcc-4.8.2/bin/g++ -o reader reader.cc messageName.pb.cc -L/home/work/.jumbo/lib/ -lprotobuf -I/home/work/.jumbo/include/

然后运行reader,得到

101
hello

 

 

又加了一个新的例子,通过管道来进行数据的传输和连接。

proto file:

message AMessage {
        required int32 a = 1;
        optional int32 b = 2;
        optional string str = 3;
}

生成头文件命令:

protoc -I=proto --cpp_out=src proto/amessage.proto
# if no '-I=proto' added, .pb.h and .pb.cpp files will be added to src/proto, but in .pb.cpp the header file is proto/.pb.h, abnormal

producer.cc

#include<stdio.h>
#include<stdlib.h>
#include<iostream>

#include"amessage.pb.h"

using namespace std;

int main(int argc,const char* argv[]) {
        AMessage msg;
        if(argc < 2) {
                fprintf(stderr, "usage:amessage a [b] [str]\n");
                return 1;
        }
        msg.set_a(atoi(argv[1]));

        if(argc > 2) {
                msg.set_b(atoi(argv[2]));
        }

        if(argc > 3) {
                msg.set_str(argv[3]);
        }

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

        return 0;
}

 

consumer.cc

#include<stdio.h>
#include<stdlib.h>
#include<iostream>

#include"amessage.pb.h"

using namespace std;

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

        AMessage msg;
        if (!msg.ParseFromIstream(&cin)) {
                cerr << "Failed to parse address book." << endl;
                return -1;
        }
        cout << msg.a() << endl;
        cout << msg.b() << endl;
        cout << msg.str() << endl;
        return 0;
}

 

编译命令:

export LD_LIBRARY_PATH=/home/work/.jumbo/lib/:$LD_LIBRARY_PATH

/opt/compiler/gcc-4.8.2/bin/g++ -o producer producer.cc amessage.pb.cc -L/home/work/.jumbo/lib/ -lprotobuf -I/home/work/.jumbo/include/

/opt/compiler/gcc-4.8.2/bin/g++ -o consumer consumer.cc amessage.pb.cc -L/home/work/.jumbo/lib/ -lprotobuf -I/home/work/.jumbo/include/

 

通过管道测试:

[src]$ ./producer 2 3 str | ./consumer 
2
3
str
[src]$ ./producer 2 3 abc | ./consumer 
2
3
abc
[src]$ ./producer 2 3 | ./consumer 
2
3

[src]$ ./producer 2 | ./consumer 
2
0

[src]$ ./producer | ./consumer 
usage:amessage a [b] [str]
[libprotobuf ERROR google/protobuf/message_lite.cc:123] Can't parse message of type "AMessage" because it is missing required fields: a
Failed to parse address book.

可以看出,对于optional的字段,接收方直接使用是可以的,会拿到默认值,int是0,str是空串。

 

(另外,测试的时候,发现在终端没有看到输出。但是管道却能够读入。原因找到是因为protobuf编码,如果只有几个数字,输出会非常小,增加了string后能看到有输出)比如:

[src]$ ./producer 2 3            
[src]$ ./producer 2 3 a
a[src]$ ./producer 2 3 abcdefghijk

abcdefghijk[src]$ 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值