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


    windows下安装Protobuf

    首先需要下载源代码
    下载如下cpp版本
    在这里插入图片描述
    解压后得到一个目录,等下CMake会用到
    如果你电脑没有CMake,需要去官网下载
    在这里插入图片描述
    双击打开下载解压后的CMake目录/bin/cmake-gui.exe
    现在,选择刚才解压的目录,和构建输出目录
    在这里插入图片描述
    然后选择Configure
    在这里插入图片描述
    选择你的VS版本,然后finish即可
    在这里插入图片描述
    点击Generate,成功后,进入生成后的目录
    在这里插入图片描述
    使用VS打开这个项目
    在这里插入图片描述
    编译libprotobuf,protoc,libprotoc这三个
    在这里插入图片描述
    编译就结束了,接下来开始使用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源文件
    在这里插入图片描述
    打开Account.pb.h头文件,发现package就是命名空间,Account是类,大概如下代码

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

    然后将生成的代码手动添加到项目中,
    接下来的步骤比较关键
    先将平台设置为所有平台
    在这里插入图片描述
    右键打开项目的属性,修改一下属性
    在这里插入图片描述
    关闭安全警告_SCL_SECURE_NO_WARNINGS
    在这里插入图片描述
    添加之前编译好的库
    在这里插入图片描述
    添加之前拷贝到项目中的库如果有多个.lib,需要用分号隔开
    在这里插入图片描述
    还要将protobuf源码中src/google文件夹拷贝到项目目录下
    在这里插入图片描述
    然后设置包含你的项目目录
    在这里插入图片描述
    然后,开始写代码了

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

    运行结果:
    在这里插入图片描述

    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文件)。在那种情况下,你可以用封装类来设计接口,以更好地适应你的应用程序的特定环境:隐藏一些数据和方法,暴露一些便于使用的函数,等等。但是你绝对不要通过继承生成的类来添加行为。这样做的话,会破坏其内部机制,并且不是一个好的面向对象的实践。

  • 相关阅读:
    守护进程(Daemon)
    Socket select的用法
    被误解的C++——磨刀不误砍柴工
    C++ 虚函数表解析
    进程间通信IPC
    pthread_join函数及linux线程
    详细讲解C++ 类的继承
    Trilogy公司的笔试题
    linux下fork的使用
    Ruby 编程规范
  • 原文地址:https://www.cnblogs.com/WindSun/p/12543066.html
Copyright © 2020-2023  润新知