protobuf编译、安装和简单使用C++ (Windows+VS平台)

本文详细介绍了在Windows环境下安装和配置Protobuf的过程,包括下载源代码、使用CMake和Visual Studio进行编译,以及如何在项目中使用Protobuf进行序列化和反序列化操作。

windows下安装Protobuf

首先需要下载源代码

下载如下cpp版本

rs1r8g9jct.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801476;1584808676&q-key-time=1584801476;1584808676&q-header-list=&q-url-param-list=&q-signature=d986e46bfa8df311ea244e437df89130ef12d5f3

解压后得到一个目录,等下CMake会用到

如果你电脑没有CMake,需要去官网下载

ot1kfnbptt.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801572;1584808772&q-key-time=1584801572;1584808772&q-header-list=&q-url-param-list=&q-signature=325d9500d193ecfd1b9fd19945c91a50b5a5a515

双击打开下载解压后的CMake目录/bin/cmake-gui.exe

现在,选择刚才解压的目录,和构建输出目录

1h9ws2bz6o.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801605;1584808805&q-key-time=1584801605;1584808805&q-header-list=&q-url-param-list=&q-signature=a5bcb38e7e0918f2c16c5c62c144ce63c40d6127

然后选择Configure

hw4b35cp14.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801621;1584808821&q-key-time=1584801621;1584808821&q-header-list=&q-url-param-list=&q-signature=67e858ec4d3bde0987e05615b42f0ccf61a9c09a

选择你的VS版本,然后finish即可

8p1esuab5k.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801632;1584808832&q-key-time=1584801632;1584808832&q-header-list=&q-url-param-list=&q-signature=b569152ec8e1ccae49e0216adf8c6b339d45f25e

点击Generate,成功后,进入生成后的目录

n1nuc6gxuj.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801642;1584808842&q-key-time=1584801642;1584808842&q-header-list=&q-url-param-list=&q-signature=3b7f61841d6b6b328c9cbfd9788c784bd9a023a1

使用VS打开这个项目

9z4nln5z6w.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801651;1584808851&q-key-time=1584801651;1584808851&q-header-list=&q-url-param-list=&q-signature=6cd51ace3463e0438002762d8a7a9a54c77a0405

编译libprotobuf,protoc,libprotoc这三个

w6ota0wxgv.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801661;1584808861&q-key-time=1584801661;1584808861&q-header-list=&q-url-param-list=&q-signature=8ea25b0985530b8208b04cb4157fe1bdd7a5e164

编译就结束了,接下来开始使用protobuf

VS中使用protobuf

在自己创建的项目下,新建一个Account.proto,内容如下

syntax = "proto3";
package IM;
message Account {
    //账号
    uint64 ID = 1;
    //名字
    string name = 2;
    //密码
    string password = 3;
}

message User {
    Account user = 1;
}

将刚才编译后的libprotobufd.libprotoc.exe拷贝到自己创建的项目下,按住shift+右键,选择打开CMD,输入protoc --cpp_out=./ Account.proto,发现目录中多了两个文件,一个.h头文件一个.cc源文件

70vpzhf5mg.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801686;1584808886&q-key-time=1584801686;1584808886&q-header-list=&q-url-param-list=&q-signature=6f867e91d6b287017c28b1c847ec38c0436da12a

打开Account.pb.h头文件,发现package就是命名空间,Account是类,大概如下代码

namespace IM {
    class Account {
        //一些方法
    };
    class User {
        //一些方法
    }
};

然后将生成的代码手动添加到项目中,

接下来的步骤比较关键

先将平台设置为所有平台

okb8ttb8bq.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801699;1584808899&q-key-time=1584801699;1584808899&q-header-list=&q-url-param-list=&q-signature=a15e43ee249a301a99bfaceaf9f80041799fe40d

右键打开项目的属性,修改一下属性

eu100jvmp6.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801722;1584808922&q-key-time=1584801722;1584808922&q-header-list=&q-url-param-list=&q-signature=ae10c32b3b0ccd72a52423519d488e30cc494330

关闭安全警告_SCL_SECURE_NO_WARNINGS

9hamzmoo3m.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801731;1584808931&q-key-time=1584801731;1584808931&q-header-list=&q-url-param-list=&q-signature=8f81de3e0ef18a3579d60704d069f47bc1e9ce7f

添加之前编译好的库

axdgk7bk4s.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801741;1584808941&q-key-time=1584801741;1584808941&q-header-list=&q-url-param-list=&q-signature=e5e469d13756d9d19cd621bdbc264a8e15297a16

添加之前拷贝到项目中的库如果有多个.lib,需要用分号隔开

rys1ibmr7d.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801751;1584808951&q-key-time=1584801751;1584808951&q-header-list=&q-url-param-list=&q-signature=3aeb175694ff309c8073d74d6cbda0a8633affed

还要将protobuf源码中src/google文件夹拷贝到项目目录下

sfp6s26eco.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801760;1584808960&q-key-time=1584801760;1584808960&q-header-list=&q-url-param-list=&q-signature=2f352d3c7cd0b9e14bf4acec613b7d46767344cf

然后设置包含你的项目目录

st62lo64kx.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801768;1584808968&q-key-time=1584801768;1584808968&q-header-list=&q-url-param-list=&q-signature=8590a02a3347405587c132cbb070b83ee8f73828

然后,开始写代码了

#include <iostream>
#include <fstream>
#include "Account.pb.h"

using namespace std;

int main(int argc, char** argv)
{
    IM::Account account1;
    account1.set_id(1);
    account1.set_name("windsun");
    account1.set_password("123456");

    string serializeToStr;
    account1.SerializeToString(&serializeToStr);
    cout <<"序列化后的字节:"<< serializeToStr << endl;


    IM::Account account2;
    if(!account2.ParseFromString(serializeToStr))
    {
        cerr << "failed to parse student." << endl;
        return -1;
    }
    cout << "反序列化:" << endl;
    cout << account2.id() << endl;
    cout << account2.name() << endl;
    cout << account2.password() << endl;

    google::protobuf::ShutdownProtobufLibrary();

    return 0;
}

运行结果:

drgplzk6r1.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1584801782;1584808982&q-key-time=1584801782;1584808982&q-header-list=&q-url-param-list=&q-signature=1d30004a14573919e753637c22a51c1a452387b4

protobuf的一些方法

标准消息函数(Standard Message Methods)。 每一个消息(message)还包含了其他一系列函数,用来检查或管理整个消息,包括:

bool IsInitialized() const; //检查是否全部的required字段都被置(set)了值。

void CopyFrom(const Person& from); //用外部消息的值,覆写调用者消息内部的值。

void Clear();   //将所有项复位到空状态(empty state)。

int ByteSize() const;   //消息字节大小

关于Debug的API。

string DebugString() const; //将消息内容以可读的方式输出

string ShortDebugString() const; //功能类似于,DebugString(),输出时会有较少的空白

string Utf8DebugString() const; //Like DebugString(), but do not escape UTF-8 byte sequences.

void PrintDebugString() const;  //Convenience function useful in GDB. Prints DebugString() to stdout.

关于解析&序列化(Parsing and Serialization)。

最后,每一个protocol buffer类都有读写你所选择的消息类型的函数。它们包括:

**注意:** protocol buffers和面向对象的设计 protocol buffer类通常只是纯粹的数据存储器(就像C++中的结构体一样);它们在对象模型中并不是一等公民。如果你想向生成的类中添加更丰富的行为,最好的方法就是在应用程序中对它进行封装。如果你无权控制.proto文件的设计的话,封装protocol buffers也是一个好主意(例如,你从另一个项目中重用一个.proto文件)。在那种情况下,你可以用封装类来设计接口,以更好地适应你的应用程序的特定环境:隐藏一些数据和方法,暴露一些便于使用的函数,等等。但是你绝对不要通过继承生成的类来添加行为。这样做的话,会破坏其内部机制,并且不是一个好的面向对象的实践。
bool SerializeToString(string* output) const; //将消息序列化并储存在指定的string中。注意里面的内容是二进制的,而不是文本;我们只是使用string作为一个很方便的容器。

bool ParseFromString(const string& data); //从给定的string解析消息。

bool SerializeToArray(void * data, int size) const  //将消息序列化至数组

bool ParseFromArray(const void * data, int size)    //从数组解析消息

bool SerializeToOstream(ostream* output) const; //将消息写入到给定的C++ ostream中。

bool ParseFromIstream(istream* input); //从给定的C++ istream解析消息。

这些函数只是用于解析和序列化的几个函数罢了。请再次参考Message API reference以查看完整的函数列表。

注意: protocol buffers和面向对象的设计 protocol buffer类通常只是纯粹的数据存储器(就像C++中的结构体一样);它们在对象模型中并不是一等公民。如果你想向生成的类中添加更丰富的行为,最好的方法就是在应用程序中对它进行封装。如果你无权控制.proto文件的设计的话,封装protocol buffers也是一个好主意(例如,你从另一个项目中重用一个.proto文件)。在那种情况下,你可以用封装类来设计接口,以更好地适应你的应用程序的特定环境:隐藏一些数据和方法,暴露一些便于使用的函数,等等。但是你绝对不要通过继承生成的类来添加行为。这样做的话,会破坏其内部机制,并且不是一个好的面向对象的实践。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值