protobuf

1.下载protobuf

#wget -c https://github.com/protocolbuffers/protobuf/releases/download/v3.7.1/protobuf-cpp-3.7.1.tar.gz

或者百度网盘下载protobuf3.7.1 提取码: wfu5

下载后,解压文件protobuf-cpp-3.7.1.tar.gz,在解压得到的protobuf-3.7.1目录下执行以下命令,--prefix指定安装的根目录

$ ./configure --prefix=/usr/local

$ make

$ make check

$ sudo make install

# ldconfig

tobuf 三个关键字required、optional、repeated的理解 原创
2018-09-18 09:00:25
required关键字
顾名思义,就是必须的意思,数据发送方和接收方都必须处理这个字段,不然还怎么通讯呢

optional关键字
字面意思是可选的意思,具体protobuf里面怎么处理这个字段呢,就是protobuf处理的时候另外加了一个bool的变量,用来标记这个optional字段是否有值,发送方在发送的时候,如果这个字段有值,那么就给bool变量标记为true,否则就标记为false,接收方在收到这个字段的同时,也会收到发送方同时发送的bool变量,拿着bool变量就知道这个字段是否有值了,这就是option的意思。

这也就是他们说的所谓平滑升级,无非就是个兼容的意思。

其实和传输参数的时候,给出数组地址和数组数量是一个道理。

repeated关键字
字面意思大概是重复的意思,其实protobuf处理这个字段的时候,也是optional字段一样,另外加了一个count计数变量,用于标明这个字段有多少个,这样发送方发送的时候,同时发送了count计数变量和这个字段的起始地址,接收方在接受到数据之后,按照count来解析对应的数据即可。

其他说明
上述内容是在proto2版本下面的关键字说明,在proto3上,关键字做了很多调整,比如去掉了required,默认什么都不写,就是required,就是必须的,如果想使用optional,可以使用,但是protobuf-c的实现(即C语言版本的protobuf)没有支持该关键字,所以最好改成oneof关键字代替,效果是一样的,repeated保持和proto2版本一直,整体说proto3的语法简洁了很多。

 

2. 测试

person.proto

syntax = "proto3";

package person;
message Person{
    string id=1;
    string name=2;
    string addr = 3;
    string test = 1000;
}

//protoc --cpp_out=. person.proto

 

 

/*!
* Auth: xor
* Date: 2019-6-9
* File: personWrite.cpp
* Class: %{Cpp:License:ClassName} (if applicable)
* Brief:
* Note:
 */
#include "person.pb.h"
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string>
#include <unistd.h>

using namespace std;
using namespace person;

int main(int argc,char **argv){
    person::Person person;
    person.set_id("111");
    person.set_name("China");
    person.set_addr("Aisa");
    person.set_test("ttttt");

    // serialize
    string output = "";
    if(!person.SerializeToString(&output))
    {
        perror("failed to write person.\n");
        return -1;
    }

    cout << "output:" << output << endl;

    // serialize data to file
    fstream os("./person.info", ios::out | ios::trunc | ios::binary);
    if(!person.SerializeToOstream(&os))
    {
        perror("failed to write person");
        return -1;
    }
    printf("hello world!\n");
    return 0;
}

// g++11 personWrite.cpp person.pb.cc -o xpW -lprotobuf -lpthread

 

#include "person.pb.h"
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string>
#include <unistd.h>

using namespace std;
using namespace person;

int main(int argc,char **argv){
    person::Person person;
    int fd = open("./person.info", O_EXCL);
    assert(fd > 0);

    if(!person.ParseFromFileDescriptor(fd))
    {
        perror("failed to parse msg");
        return -1;
    }

    cout << "output:" << person.id() << " name:" << person.name() << " addr:" << person.addr() << " test:" << person.test() << endl;

    printf("hello world!\n");
    return 0;
}

// g++11 personRead.cpp person.pb.cc -o xpR -lprotobuf -lpthread

 

posted @ 2019-05-17 19:31  PKICA  阅读(297)  评论(0编辑  收藏  举报