protobuf3 安裝編譯測試

ubuntu20.04 安裝Protobuf3.14.0 及簡單示例

1、下載地址:Protobuf3.14.0
2、解壓編譯

unzip -a protobuf-all-3.14.0.zip
cd protobuf-3.14.0/
./configure
make -j4
sudo make install

安裝好後出現了點小插曲
在这里插入图片描述百度解決方案:

sudo ldconfig

安裝成功後如下圖:
在这里插入图片描述官方示例
包含以下幾個文件
在这里插入图片描述其中demo.cpp、project.proto是我在百度上搜的簡易教程,我覺得對於我這種初學者更容易理解,首先看下這個簡易示例:
project.proto文件,類似於json,xml,其內容如下

syntax = "proto3";

message Account {
    uint64 ID = 1;
    string name = 2;
    string password = 3;
}

看起來類似於c++中的結構體,但是在每個字段後會有一個標號。我們先來編譯看看,

protoc -I=. --cpp_out=. project.proto 

參數-I :指定導入路徑,即在當前路徑搜索 project.proto
參數–cpp_out:指定c++項目
最後是需要編譯的文件
編譯成功後會生成兩個c++文件,如下圖:
在这里插入图片描述接下來看demo.cpp

#include <iostream>
#include <string>
#include "project.pb.h"

int main() 
{
    Account account;
    account.set_id(1000);
    account.set_name("name");
    account.set_password("1234");

    std::string s = account.SerializeAsString();
    if (!s.size()) {
        std::cerr << "error in serialize\n";
    }

    Account unserial;
    if (unserial.ParseFromString(s)) {
        std::cout << unserial.id() << '\n';
        std::cout << unserial.name() << '\n';
        std::cout << unserial.password() << '\n';
    } else {
        std::cerr << "unserialize something error!!!\n";
    }

    return 0;
}

這些函數的定義實現可以在project.pb.h、project.pb.cc中找到,然後我們對demo.c進行編譯鏈接

g++ -o demo demo.cpp project.pb.cc -lprotobuf

然後運行可以看到:
在这里插入图片描述代碼我就不做解釋了,應該很明了。
對於以上的編譯命令有可能編譯失敗,之前測試有這種情況,可以嘗試:

c++/g++ -std=c++11 demo.cpp project.pb.cc `pkg-config --cflags --libs protobuf`

以上,應該就可以成功了,具體原因還不太清楚,畢竟本人還是菜鳥中的菜鳥蛋,哈哈,稍微吐槽下自己。

官方示例
這個先放這裏,先不做注釋了。
addressbook.proto

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

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

// [START java_declaration]
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
// [END java_declaration]

// [START csharp_declaration]
option csharp_namespace = "Google.Protobuf.Examples.AddressBook";
// [END csharp_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]

add_person.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, '\n');

  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;
}

list_people.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;
}

Makefile


.PHONY: cpp

cpp: add_person_cpp list_people_cpp

clean:
	rm -f add_person_cpp list_person_cpp
	rm -f protoc_middleman addressbook.pb.cc addressbook.pb.h

protoc_middleman: addressbook.proto
	protoc -I=. --cpp_out=. addressbook.proto
	@touch protoc_middleman

add_person_cpp: add_person.cc protoc_middleman
	pkg-config --cflags protobuf
	c++ -std=c++11 add_person.cc addressbook.pb.cc -o add_person_cc `pkg-config --cflags --libs protobuf`

list_people_cpp: list_people.cc protoc_middleman
	pkg-config --cflags protobuf
	c++ -std=c++11 list_people.cc addressbook.pb.cc -o list_people_cc `pkg-config --cflags --libs protobuf`

執行make編譯完成如下圖:
在这里插入图片描述執行結果:
在这里插入图片描述先寫到這裏,後續在做下解析注釋。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值