ProtoBuf编译及使用(2024年亲自测试过,不要拿我跟那些复制粘贴的老文档比)

一直都提示找不到头文件,但我到处搜索,总算弄好了,网上真的很少protobuf比较新的编译方法,在此记录一下。

用网上的方式去弄,一直都在报各种问题。百思不得其解,以下为个人成功经验总结:

  1. 不要下载官网最新源码,很多人直接按照readme来编译,很难一次性通过。

  2. 如果直接拉github最新的源码。是没有autogen.sh或者configure文件的,当你跑去cmake里编译,他必然会提示各种变量未定义了,怎么都解决不了。
    (2024.2.3凌晨更新:最新的库没有问题,是我技术有限没有编译通过,以下为最新版本编译通过的原文教程链接:https://blog.csdn.net/wzw1609119742/article/details/119712422
    以下为我使用过程中做的笔记:
    用我這個,一定能過
    a.前提准备工作:git submodule update --init --recursive
    b.跟着作者创建好文件,确定你的起始路径为以下:XXX/protobuf/cmake/build/release
    c.复制以下命令:
    cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../../../install/release -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_TESTS=OFF ../../..
    d.以下为成功编译后的效果图:
    在这里插入图片描述
    e.开始cmake ,等待十分钟左右(可以适当的加上-j 参数加速,方法自己搜)
    f.执行 make install即可安装成功
    )

  3. 以下我直说一种一定能成功的方法,不对其他版本的错误做特殊说明。

PART1 编译源码与验证
1.11 点击链接下载3.21.12版本源码。https://github.com/protocolbuffers/protobuf/releases/tag/v2
1.12 cd protobuf-21.12/
1.13 ./autogen.sh
1.14 ./configure --prefix=/usr/local/protobuf
1.15 make
1.16 sudo make install
1.17 sudo vim /etc/profile
1.18 #添加以下内容:

#(动态库搜索路径) 程序加载运⾏期间查找动态链接库时指定除了系统默认路径之外的其他路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/protobuf/lib/
#(静态库搜索路径) 程序编译期间查找动态链接库时指定查找共享库的路径
export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/protobuf/lib/
#执⾏程序搜索路径
export PATH=$PATH:/usr/local/protobuf/bin/
#c程序头⽂件搜索路径
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/local/protobuf/include/
#c++程序头⽂件搜索路径
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/local/protobuf/include/
#pkg-config 路径
export PKG_CONFIG_PATH=/usr/local/protobuf/lib/pkgconfig/
1.18 source /etc/profile
1.19  protoc --version 
执行之后应该看到==libprotoc 3.21.12==如果出现这个版本信息则安装成功



以上为我总结信息,原文信息:https://www.cnblogs.com/zz1254/articles/17725754.html#:~:text=%E6%89%BE%E5%88%B0%E7%9B%B8%E5%AF%B9%E5%BA%94%E7%9A%84%E7%89%88%E6%9C%AC%20ProtoBuf%E4%B8%8B%E8%BD%BD%E5%9C%B0%E5%9D%80%EF%BC%9A%20https%3A%2F%2Fgithub.com%2Fprotocolbuff,%E6%88%91%E4%B8%8B%E8%BD%BD%E7%9A%84%E6%98%AF3.21.12%20https%3A%2F%2Fgithub.com%2Fprotocolbuffers%2Fprotobuf%2Freleases%2Ftag%2Fv21.12%20wget%20https%3A%2F%2Fgithub.com%2Fprotocolbuffers%2Fprotobuf%2Freleases%2Fdownload%2Fv21.12%2Fprotobuf-all-21.12.tar.gz




PART2 撰写测试用例

参考链接:https://zhuanlan.zhihu.com/p/641283776

  1. 在本地新建一个文件: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 people = 1;
}
  1. ./usr/local/protobuf/bin/protoc --cpp_out=. addressbook.proto(这个是绝对路径能保证你绝对不出错,如果你执行protoc --version得到的不是libprotoc 3.21.12版本,才这样做。如果是,则直接protoc --cpp_out=. addressbook.proto)

3.编写reader.cpp

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

// 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.has_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;
      }
      cout << phone_number.number() << 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;
}

3.编写writer.cpp

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

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

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

编译:
c++ -std=c++14 writer.cpp addressbook.pb.cc -o writer -lpthread -lprotobuf
c++ -std=c++14 reader.cpp addressbook.pb.cc -o reader -lpthread -lprotobuf
4.测试写出来的东西
在这里插入图片描述

测验完毕。
备注:
千万不要抄第二篇博客的安装protobuf软件手段,一定编译不出来!他写的这个我机器上没编译过。如果你抄了,请卸载:sudo apt autoremove protobuf-compiler 下图为我参考第二篇博客走的弯路。被这个坑了。
在这里插入图片描述

PART 3 拓展-protobuf-C的使用

参考链接吧,这个太简单了
https://blog.csdn.net/zb313982521/article/details/110341454
以下只介绍我用的源码版本及编译过程即可:
源码版本:https://github.com/protobuf-c/protobuf-c/releases/tag/v1.4.1
点击下面这个就会自动下载了,
在这里插入图片描述
注意,这个版本没有autogen文件,我是跟着readme自主编译的:./configure && make && make install
在这里插入图片描述
编译完成自己学着readme做了个测试
make check
在这里插入图片描述
这个是敲完source /etc/profile后,查看版本信息的情况。
在这里插入图片描述
protobuf测试结果:
在这里插入图片描述
插曲:我执行student会报错但是去我的安装路径上去找,是找得到的,还不明白为什么,因此用了个手动引入环境变量来规避该问题:
在这里插入图片描述
规避后的成功执行效果:
在这里插入图片描述
本文章完毕

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值