zoukankan      html  css  js  c++  java
  • Proto在C++的使用

    Message对象

    1: 每一个Message对象都包含两个对象:
    (1)google::protobuf::Descriptor 描述对象,是Message所有Filed的一个集合,它又包含了
    FieldDescriptor 对象; 每个filed都对应一个FieldDescriptor;
    (2)google::protobuf::Reflection 反射对象, 通过它 + FieldDescriptor, 能set/get filed对象的值;

    2: 每一个Message对象,可以通过统一的对象工厂来构建, 根据协议生成了代码后,只要传入Message的名字,就能构建出对应的Message的类的实例;

    #define _CRT_SECURE_NO_WARNINGS
    #include <string.h>
    #include <stdlib.h>
    
    #include <iostream>
    #include <string>
    using namespace std;
    #include "../proto/person.pb.h"
    
    #if 0
    int main(int argc, char** argv)
    {
        //1.定义要传送数据的对象  对应message后跟的名字
        Person p;  
        //2.初始化对象
        p.set_name("大圣");
        p.set_email("wukong@163.com");
        p.set_age(1700);
    
        cout << p.name() << " " << p.age() << " " << p.email() << endl;
        //3.将这个数据对象序列化
        string out;
        p.SerializeToString(&out);
    
        //4.使用string对象里面存放的数据,反序列化数据对象
        Person monkey;
        monkey.ParseFromString(out);
        cout << monkey.name() << " " << monkey.age() << " " << monkey.email() << endl;
        system("Pause");
        return 0;
    }
    #else
    //传递一个信息类型的字符串,那么这个工厂就会帮我们构造出一个对应的类的实例
    //"Person"字符串-->Person的实例 -->返回的是一个基类Message类的指针
    //基类指针 指向子类实例
    //create_message -->delete 来删除对象实例
    google::protobuf::Message* create_message(const char* typeName) {
        //message类
        google::protobuf::Message* message = NULL;
    
        // 根据名字,找到message的描述对象
        const google::protobuf::Descriptor* descriptor =
            google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(typeName);
        if (descriptor) {
            //根据描述对象到对象工厂里面,生成对应的模板对象
            const google::protobuf::Message* prototype =
                google::protobuf::MessageFactory::generated_factory()->GetPrototype(descriptor);
            if (prototype) {
                //根据模板对象克隆一个
                message = prototype->New();
            }
        }
        return message;
    }
    
    int main(int argc, char** argv)
    {
        //基类的message-->Person类的实例
        google::protobuf::Message* msg = create_message("Person");
    
        /*
        Person* hou = (Person*)msg;
        hou->set_name("大圣");
        cout << hou->name() << endl;
        */
    
        /*
            每个message对象包含两个对象:
            google::protobuf::Descriptor 描述对象-->获取message的描述信息 字段名以及类型等-->包含每一个field的描述
            google::protobuf::Reflection 反射对象--> 使用这个对象 + field描述, 能get/set每个field的值
        */
    
        const google::protobuf::Descriptor* des = msg->GetDescriptor();
        const google::protobuf::Reflection* ref = msg->GetReflection();
    
        //设置
        // name
        // 1. 通过des获取
        const google::protobuf::FieldDescriptor* fd_des = des->FindFieldByName("name"); //通过字段名字设置数据
        // 2.通过ref进行设置
        ref->SetString(msg, fd_des, "大圣");
    
        //age
        fd_des = des->FindFieldByNumber(2); //通过字段标识号设置数据
        ref->SetInt32(msg, fd_des, 1500);
        //email
        fd_des = des->FindFieldByName("email");
        ref->SetString(msg, fd_des, "wukong@163.com");
        //数组 使用AddInt32一个一个追加进去
        fd_des = des->FindFieldByName("set");
        ref->AddInt32(msg, fd_des, 1);
        ref->AddInt32(msg, fd_des, 2);
        ref->AddInt32(msg, fd_des, 3);
        ref->AddInt32(msg, fd_des, 4);
    
        //获取
        for (int i = 0; i < des->field_count(); i++)
        {
            //获取每一个field描述对象
            const google::protobuf::FieldDescriptor* fd = des->field(i);
            //(1) 获取名字
            cout << fd->name() << endl;     //字段名字 不是数据 如:name age
            cout << fd->type_name() << endl;     //类型
            cout << fd->cpp_type_name() << endl;     //c++类型 bytes被换成了string
            // 判断字段规则
            // fd->is_repeated() 是否是数组
            // fd->is_optional() 是否是非必须
            // fd->is_required() 是否是必须
            if (!fd->is_repeated()) {
                //获取数据
                switch (fd->cpp_type())
                {
                case google::protobuf::FieldDescriptor::CppType::CPPTYPE_INT32:
                    cout << ref->GetInt32(*msg, fd) << endl;
                    break;
                case google::protobuf::FieldDescriptor::CppType::CPPTYPE_STRING:
                    cout << ref->GetString(*msg, fd) << endl;
                    break;
                }
            }
            else {
                for (int j = 0; j < ref->FieldSize(*msg, fd); j++)  //ref->FieldSize(*msg, fd)获取数组长度
                {
                    switch (fd->cpp_type())
                    {
                    case google::protobuf::FieldDescriptor::CppType::CPPTYPE_INT32:
                        cout << ref->GetRepeatedInt32(*msg, fd,j) << " ";  //使用GetRepeatedInt32 便利数组
                        break;
                    case google::protobuf::FieldDescriptor::CppType::CPPTYPE_STRING:
                        cout << ref->GetRepeatedString(*msg, fd,j) << " ";
                        break;
                    }
                }
                cout << endl;
            }
            
           
    
            cout << fd->number() << endl;        //获取字段标识号
        }
        //删除
        delete msg;
        system("Pause");
        return 0;
    }
    #endif
  • 相关阅读:
    Validator 字段验证
    DRF实现发送短信验证码接口
    云片网发送短信验证码
    DRF自定义用户认证
    php服务器端与android客户端通信问题
    转 java调用php的webService
    Ubuntu12.04安装vim7.3
    ubuntu12.10更新源
    源列表
    Ubuntu 12.10 用wubi安装到硬盘中
  • 原文地址:https://www.cnblogs.com/yifengs/p/15268289.html
Copyright © 2011-2022 走看看