protocol buffer入门

protocol buffer入门

本文档完全参考google protocol buffer编写:https://developers.google.com/protocol-buffers/docs/cpptutorial

1、编译protocol buffer

生成protoc和一些共享库

#安装依赖库  g++依赖个人来定
yum install -y  autoconf automake libtool curl make g++ unzip gcc gcc-c++
#安装包https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-cpp-3.17.3.tar.gz
#这个是cpp版本的
tar -zxf protobuf-cpp-3.17.3.tar.gz
cd protobuf-3.17.3/
./autogen.sh
./configure
make && make install

#默认安装在/usr/local/下

2、编写proto

//addressbook.proto
syntax="proto2";

package tutorial;

message Person {
    optional string name = 1;
    optional int32 id = 2;
    optional string email = 3;

    enum PhoneType {
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
    }

    message PhoneNumber {
        optional string number = 1;
        optional PhoneType type = 2 [default = HOME];
    }

    repeated PhoneNumber phones = 4;
}

message AddressBook {
    repeated Person person = 1;
}

3、根据proto生成c++文件

mkdir build
protoc -I./ --cpp_out=./build ./addressbook.proto
#生成的.h和.cc文件在build下

4、编写测试代码

#include <iostream>
#include <string>
#include <fstream>
#include "addressbook.pb.h"
using namespace std;

void PromptForAddress(tutorial::Person *person)
{
    cout << "Enter person ID number: ";
    int id;
    cin >> id;
    person->set_id(id);
    cin.ignore(256,'\n');

    cout << "Enter name: ";
    getline(cin, *person->mutable_name());

    cout << "Enter email address: ";
    string email;
    getline(cin,email);
    if(!email.empty()){
        person->set_email(email);
    }

    while (true) {
    cout << "Enter a phone number (or leave blank to finish): ";
    string number;
    getline(cin, number);
    if (number.empty()) {
      break;
    }

    tutorial::Person::PhoneNumber* phone_number = person->add_phones();
    phone_number->set_number(number);

    cout << "Is this a mobile, home, or work phone? ";
    string type;
    getline(cin, type);
    if (type == "mobile") {
      phone_number->set_type(tutorial::Person::MOBILE);
    } else if (type == "home") {
      phone_number->set_type(tutorial::Person::HOME);
    } else if (type == "work") {
      phone_number->set_type(tutorial::Person::WORK);
    } else {
      cout << "Unknown phone type.  Using default." << endl;
    }
    }
}

int main(int argc, char* argv[]) {
  // Verify that the version of the library that we linked against is
  // compatible with the version of the headers we compiled against.
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  if (argc != 2) {
    cerr << "Usage:  " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
    return -1;
  }

  tutorial::AddressBook address_book;

  //这里被我注释掉,是刚开始没有那个文件,执行过一次后就可以放开了
  /*{
    // Read the existing address book.
    fstream input(argv[1], ios::in | ios::binary);
    if (!input) {
      cout << argv[1] << ": File not found.  Creating a new file." << endl;
    } else if (!address_book.ParseFromIstream(&input)) {
      cerr << "Failed to parse address book." << endl;
      return -1;
    }
  }*/

  // Add an address.
  PromptForAddress(address_book.add_person());

  {
    // Write the new address book back to disk.
    fstream output(argv[1], ios::out | ios::trunc | ios::binary);
    if (!address_book.SerializeToOstream(&output)) {
      cerr << "Failed to write address book." << endl;
      return -1;
    }
  }

  // Optional:  Delete all global objects allocated by libprotobuf.
  google::protobuf::ShutdownProtobufLibrary();

  return 0;
}

5、编译测试代码

#添加环境变量,否则pkg-config找不到protobuf的
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

###############
[root@jslab build]# pkg-config --cflags --libs protobuf
-pthread -I/usr/local/include  -L/usr/local/lib -lprotobuf -lpthread
###############


#编译代码,这里需要加上-std=c++11否则会报错,应为protobuf有很多c++11的新特性
g++ test_seri.cc addressbook.pb.cc -std=c++11 `pkg-config --cflags --libs protobuf`

#生成的a.out不能执行,libprotobuf.so.28 => not found
#############
[root@jslab build]# ldd a.out
        linux-vdso.so.1 =>  (0x00007fff9a978000)
        libprotobuf.so.28 => not found 
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f5da1fd3000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f5da1ccb000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f5da19c9000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f5da17b3000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f5da13e5000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f5da21ef000)
#############

#添加路径
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

#执行
./a.out res
#############
[root@jslab build]# touch res
[root@jslab build]# ./a.out res
Enter person ID number: 12
Enter name: hello
Enter email address: helo@word.com
Enter a phone number (or leave blank to finish): 123456
Is this a mobile, home, or work phone? work
Enter a phone number (or leave blank to finish): 234567
Is this a mobile, home, or work phone? mobile
#############

参考:
https://blog.csdn.net/cc1949/article/details/105655377
https://blog.csdn.net/Programmer_H/article/details/8890800

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值