Mac下Protobuf编译及使用记录

前言

信息传输格式,相比于xml和json的纯文本格式,protocal是经过序列化的,显然空间占用更小,但也导致了读取比较复杂。

正常读取需要protobuf文件需要第三方库的支持,因此记录一下自己的编译使用步骤。

设计思路

C++中protocal的使用思路是通过程序自动创建一个头文件,在项目中包含该头文件后,即可支持对protocal协议的读写。因此,在使用时就需要先编写protocal协议内容,然后根据内容生成对应的头文件和函数体文件。所以,当protocal协议内容发生变动,就需要重新生成对应的头文件,严重时有可能导致项目的重大变更。

完整使用protobuf的项目,涉及到源代码、编译支持工具、库文件、协议转换程序,然后就可以项目中引用protobuf了。

源文件和编译支持工具用于生成协议转换程序、库文件;
协议转换程序和自定义协议内容文件可以生成对应的头文件;
源文件、库文件和协议对应的头文件就可以在项目中包含使用了。

使用记录

Google Protocal Buffer 的项目地址是 https://github.com/protocolbuffers/protobuf,C++编译参考https://github.com/protocolbuffers/protobuf/tree/master/src

我这边记录一下我的非官方的编译步骤:

// 安装编译工具  // Mac可使用brew进行安装
// sudo apt-get install autoconf automake libtool curl make g++ unzip
sudo brew install autoconf automake libtool curl make g++ unzip
// 获取源文件
git clone https://github.com/protocolbuffers/protobuf.git
// 进入源文件目录
cd protobuf
// 更新子模块 // 貌似只与google test有关
git submodule update --init --recursive

下面好想就只有我这么做了,因为网上确实没搜到这么做的

// 进入构建目录
cd cmake
// 创建生成目录
mkdir build
// 进入目标路径
cd build
// 创建编译文件
cmake ..
// 编译  // -j4编译加速,4代表使用4核心进行编译
make -j4

protobuf项目下的操作结束了,会在cmake/build目录下生成protoc可执行文件和libprotobuf.a静态库文件。

VSCode 下的操作记录如下:
1.创建proto协议内容文件msg.proto

syntax="proto3";
package lm; 
message helloworld 
{ 
    int32     id = 1;  // ID   
    string    str = 2;  // str  
    int32     opt = 3;  //optional field 
}

2.bash中生成读写文件

// --cpp_out=. : 在当前目录生成c++文件
// msg.proto   : 协议文件为“msg.proto”
// 生成的文件名为”msg.pb.h“和”msg.pb.cc“
protoc --cpp_out=. msg.proto

3.创建程序入口文件write.cpp

// g++ -o write write.cpp msg.pb.cc --std=c++11 -I. -L. -lprotobuf 
#include "msg.pb.h"
#include <fstream>
#include <iostream>
using namespace std;
int main(void)
{
    lm::helloworld msg1;
    msg1.set_id(101);
    msg1.set_str("hello");
    fstream output("./log", ios::out | ios::trunc | ios::binary);
    if (!msg1.SerializeToOstream(&output))
    {
        cerr << "Failed to write msg." << endl;
        return -1;
    }
    return 0;
}

4.将git项目目录下的”src/google“文件夹、”msg.pb.h“文件、”msg.pb.cc“文件、”libprotobuf.a“文件、”write.cpp“文件拷贝到同一文件夹下,然后执行以下编译命令。

// -I. :指定头文件目录为当前文件夹
// -L. :指定静态链接库目录为当前文件夹
// -lprotobuf :链接”libprotobuf.a“静态库文件  // "lib" + "protobuf" + ".a"
g++ -o write write.cpp msg.pb.cc --std=c++11 -I. -L. -lprotobuf

此时即可执行目标程序了

./write