文章目录

  • 前言
  • 下载安装Protocol Compiler和Protobuf Runtime
  • 下载
  • 编译安装Protobuf Runtime
  • 使用Protocol Compiler生成.cc和.h文件
  • VS工程的配置
  • 测试

前言

Protobuf是一种数据交换格式,类似于Json和XML。但Portobuf序列化后的包的大小要比Json和XML小很多,解包的速度也要快很多。这就是为什么需要学Protobuf的原因,在追求通讯速度的环境下,Protobuf要优于Json和XML。但Protobuf唯一稍微麻烦的是,protobuf没有可读性,必须得借助工具来解析。 工具和版本:

  • VS2019
  • CMake 3.19.2
  • protobuf 3.17.3

这篇教程主要是参考了官方教程来做的,英文好的同学可以自行去Protocol Buffers google 开发者网站查阅。要注意访问google网站需要科学上网。 先介绍下整个步骤:

  1. 下载Protocol Compiler和Protobuf Runtime
  2. 用CMake编译Protobuf Runtime生成libprotobufd.lib和libprotocd.lib库文件
  3. 编写自定义的.proto文件
  4. 用Protocol Compiler即protoc.exe生成.h和.cc文件
  5. 在VS工程中链接库文件,将google文件夹引入工程。引入生成的.h和.cc文件

下载安装Protocol Compiler和Protobuf Runtime

下载

建议英语好的同学,先阅读protobuf仓库主页 readme文件了解初步指南,再阅读protocbuf C++的安装指南 readme文件,了解不同系统的安装方法,最后阅读用CMake和MSVC编译Runtime readme文件,来完成库的生成。 第一手资料才最可靠。 先简单介绍下这两个东西。 Protocol Compiler是用来将我们自定义的.proto文件生成对应的数据结构源文件如C++的.cc和.h文件,改变输出参数也可以生成python的.py文件,java的.java文件等。

官方的语言支持有:C++ Java Python Objective-C C# Javascript Ruby Go PHP Dart。

Protobuf Runtime是用来生成库文件并且提供必要的文件,集成到你的代码里使用的。其实如果语言用的是C++的话,是不需要下载Protocol Compiler的,在编译时会生成protoc.exe来支持我们编译.proto文件。Protocol Compiler只是为了方便那些非C++语言的,这里我们还是两个都下载。

首先我们访问protobuf git仓库 releasesv3.17.3,如图,我们下载标识的两个文件(根据自己的系统的语言来),第一个就是runtime,第二个是compiler。

protobuf java代码生成proto protobuf生成c++文件_c++

编译安装Protobuf Runtime

编译安装Runtime只需用到CMake和Visual Studio。 这里我用的是Developer Command Prompt for VS 2019命令行工具的,其实也可以用cmake的GUI的,参考protobuf(C++)的使用(windows)。

ps:Developer Command Prompt for VS 与CMD的命令基本相同。只是Prompt for VS和CMD的环境不同,Prompt for VS可以调用Visual studio的所有工具如msbuild,而CMD必须要设置好PATH才能调用。

首先做一些准备工作,新建一个文件夹protobuftest,将下载的Runtime压缩包解压到protobuftest文件夹内。在protobuftest文件夹新建一个install文件夹。

protobuf java代码生成proto protobuf生成c++文件_protobuf_02

后面的工作全部通过敲命令完成。

第二步,从应用中找到Developer Command Prompt for VS 2019应用,打开以后先进入指定盘符,然后敲入以下命令。

该命令的作用是,在cmake文件夹里创建一个build\release文件夹,并进入该目录。

D:\VS2019>E:
E:\>cd protobuftest\protobuf-cpp-3.17.3\cmake & mkdir build & cd build & mkdir release & cd release

第三步,输入以下指令,-G 后面的参数是选择生成什么makefile,-D后面跟的都是设置的参数CMAKE_BUILD_TYPE参数是编译类型,CMAKE_INSTALL_PREFIX是安装路径,给后面namke install指令指定路径的。编译的是cmake目录。这里的^符号是换行的意思,在CMD也能这么使用。

E:\protobuftest\protobuf-cpp-3.17.3\cmake\build\release>cmake -G "NMake Makefiles" ^
 -DCMAKE_BUILD_TYPE=Debug ^
 -DCMAKE_INSTALL_PREFIX=../../../../install ^
 ../..

然后输入nmake,开始编译。编译的时候感兴趣的可以去观察release文件夹。

E:\protobuftest\protobuf-cpp-3.17.3\cmake\build\release>nmake

protobuf java代码生成proto protobuf生成c++文件_CMake_03

编译完成后,输入nmake install指令。在install之前可以输入nmake check进行test,可能出现错误,但这边先不管,只要大多数case没有错误,我们使用起来是没有问题的。

E:\protobuftest\protobuf-cpp-3.17.3\cmake\build\release>nmake install

可以观察到install文件夹已经有了以下目录。

protobuf java代码生成proto protobuf生成c++文件_protobuf_04

这里的bin目录下就是protoc.exe也就是我们的Protocol Compiler工具,include目录是我们需要引用到工程的文件,lib是静态库,也需要在工程设置中链接。

使用Protocol Compiler生成.cc和.h文件

首先我们写一个简单的proto文件。

syntax = "proto3";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

这里我们可以使用从git上下载下来的protoc.exe也可以用我们的install\bin目录下的protoc.exe。进入protoc.exe所在目录,按shifit+鼠标右键,选择在此处打开powershell窗口。输入以下命令:

PS E:\protobuftest\install\bin> .\protoc.exe --proto_path=.\ --cpp_out=.\ .\myproto.proto

这里proto_path指定的是.proto文件的目录,cpp_out是设置输出是用于C++的.cc和.h文件,后面跟的参数是生成文件的位置。

此时我们可以得到.cc和.h文件。

protobuf java代码生成proto protobuf生成c++文件_CMake_05

VS工程的配置

因为我们编译的是Debug的库,所以配置要选择Debug,平台要选择Win32平台。

  1. 配置 C/C++ protobuf java代码生成proto protobuf生成c++文件_c++_06 常规 protobuf java代码生成proto protobuf生成c++文件_c++_06 附加包含目录,设置include的文件目录
  2. 配置 链接器protobuf java代码生成proto protobuf生成c++文件_c++_06 常规 protobuf java代码生成proto protobuf生成c++文件_c++_06 附加库目录,设置lib文件目录
  3. 配置 链接器protobuf java代码生成proto protobuf生成c++文件_c++_06 输入 protobuf java代码生成proto protobuf生成c++文件_c++_06 附加依赖项,将三个lib文件填进去libprotobufd.lib;libprotobuf-lited.lib;libprotocd.lib

ps:debug的库带d,release的库不带。

protobuf java代码生成proto protobuf生成c++文件_ios_12

  1. 最后设置 高级protobuf java代码生成proto protobuf生成c++文件_c++_06高级属性protobuf java代码生成proto protobuf生成c++文件_c++_06MFC的使用,改成在静态库中使用MFC

MFC:Microsoft Foundation Class 微软基础类库

protobuf java代码生成proto protobuf生成c++文件_#include_15

测试

使用如下代码进行测试

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

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

int main()
{
    //std::cout << "Hello World!\n";
    SearchRequest data;
    data.set_query("yy");
    data.set_page_number(10);
    data.set_result_per_page(12);
    cout <<"origin data: "<< data.query() << "," << data.page_number() << "," << data.result_per_page()<<endl;
    fstream output("./log", ios::out | ios::trunc | ios::binary);
    //此处是执行序列化的操作,该方法执行完后,对应生成的二进制文件就保存在log文件中
    if (!data.SerializeToOstream(&output))
    {
        cerr << "failed to write msg." << endl;
        return -1;
    }
    getchar();
    if (output.is_open())
    {
        output.close();
    }
    SearchRequest parsedata;
    fstream input("./log", ios::in | ios::binary);
    //此处是执行反序列化的操作
    if (!parsedata.ParseFromIstream(&input))
    {
        cerr << "failed to parse message." << endl;
        return -1;
    }
    cout <<"after serialization and parse: "<< parsedata.query() << "," << parsedata.page_number() << "," << parsedata.result_per_page()<<endl;

    return 0;
    
}

工程我已经上传了,包括编译好的install文件夹,需要修改一下库和包含的路径才能使用,参考上文。资源链接 测试代码的作用是,将信息序列化后,存到工程目录的log文件下,然后在通过读取log文件,反序列化得到信息。

输出结果如下:

protobuf java代码生成proto protobuf生成c++文件_protobuf_16