您现在的位置是:首页 >学无止境 >在C++中关于protobuf的问题使用网站首页学无止境

在C++中关于protobuf的问题使用

普通市民小鹏 2023-04-27 22:30:02
简介在C++中关于protobuf的问题使用

第一次接触这个玩意,正在记录,本人的系统是ubuntu20.04。

0 首先进行安装这个编译器

1安装 protobuf

打开终端,输入以下命令来安装 protobuf:

sudo apt-get update
sudo apt-get install protobuf-compiler libprotobuf-dev
查看是不是安装成功了
protoc --version
如果出现这个
libprotoc 3.6.1  数字表述版本号

2安装好了后进行数据格式的定义

创建一个文件

touch addressbook.proto

在这个文本中输入下面的代码,保存

// [START declaration]
syntax = "proto3";
package tutorial;

import "google/protobuf/timestamp.proto";
// [END declaration]

// [START messages]
message Person {
  string name = 1;
  int32 id = 2;  // Unique ID number for this person.
  string email = 3;

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

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;

  google.protobuf.Timestamp last_updated = 5;
}

// Our address book file is just one of these.
message AddressBook {
  repeated Person people = 1;
}
// [END messages]

3 对上述文件进行编译

protoc -I=. --cpp_out=. addressbook.proto

在当前目录下进行编译,会生成两个文件一个.cc一个.h文件。

4重新创建一个文件testwrite.cc

#include <ctime>
#include <fstream>
#include <google/protobuf/util/time_util.h>
#include <iostream>
#include <string>

#include "addressbook.pb.h"

using namespace std;

using google::protobuf::util::TimeUtil;

// This function fills in a Person message based on user input.
void PromptForAddress(tutorial::Person *person)
{
  cout << "Enter person ID number: ";
  int id;
  cin >> id;
  person->set_id(id);
  cin.ignore(256, '
');

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

  cout << "Enter email address (blank for none): ";
  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;
    }
  }
  *person->mutable_last_updated() = TimeUtil::SecondsToTimestamp(time(NULL));
}

// Main function:  Reads the entire address book from a file,
//   adds one person based on user input, then writes it back out to the same
//   file.
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_people());

  {
    // 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.1如果你不是在IDE下进行编译的就直接G++编译

g++ testwrite.cc addressbook.pb.cc -o testwrite -lprotobuf -lthread
生成一个testwrite文件,可以进行运行。

5.2运行命令

./testwrite addressbook.data
后面跟着这个addressbook.data意思是创建一个addressbook.data这样的二进制文件,进行数据储存。
运行后进行数据的写入,写入的内容就是你刚才定义的那个数据格式。
全部写完后结束。

6 下面进行读取刚才写入的数据

创建一个代码读的代码
touch testread.cc

#include <fstream>
#include <google/protobuf/util/time_util.h>
#include <iostream>
#include <string>

#include "addressbook.pb.h"

using namespace std;

using google::protobuf::util::TimeUtil;

// Iterates though all people in the AddressBook and prints info about them.
void ListPeople(const tutorial::AddressBook &address_book)
{
    for (int i = 0; i < address_book.people_size(); i++)
    {
        const tutorial::Person &person = address_book.people(i);

        cout << "Person ID: " << person.id() << endl;
        cout << "  Name: " << person.name() << endl;
        if (person.email() != "")
        {
            cout << "  E-mail address: " << person.email() << endl;
        }

        for (int j = 0; j < person.phones_size(); j++)
        {
            const tutorial::Person::PhoneNumber &phone_number = person.phones(j);

            switch (phone_number.type())
            {
            case tutorial::Person::MOBILE:
                cout << "  Mobile phone #: ";
                break;
            case tutorial::Person::HOME:
                cout << "  Home phone #: ";
                break;
            case tutorial::Person::WORK:
                cout << "  Work phone #: ";
                break;
            default:
                cout << "  Unknown phone #: ";
                break;
            }
            cout << phone_number.number() << endl;
        }
        if (person.has_last_updated())
        {
            cout << "  Updated: " << TimeUtil::ToString(person.last_updated()) << endl;
        }
    }
}

// Main function:  Reads the entire address book from a file and prints all
//   the information inside.
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 (!address_book.ParseFromIstream(&input))
        {
            cerr << "Failed to parse address book." << endl;
            return -1;
        }
    }

    ListPeople(address_book);

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

    return 0;
}


7创建完了进行编译直接G++编译

g++ testread.cc addressbook.pb.cc -o testwrite -lprotobuf -lthread

8然后运行

./testread addressbook.data

就会打印出来你刚才的数据。

*******如果用IDE的就添加CMakeLists.txt

cmake_minimum_required(VERSION 3.1)

set(CMAKE_CXX_STANDARD 14)
project(write)

include_directories(${CMAKE_CURRENT_SOURCE_DIR})

add_executable(write testwrite.cpp testread.cpp addressbook.pb.cc addressbook.pb.h )

target_link_libraries(write PRIVATE protobuf pthread)

作者 :https://blog.csdn.net/qq_41950508/article/details/127126215

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。