google的protobuf简单介绍
google的protobuf是一种轻便高效的结构化数据存储格式,在通信协议和数据存储等领域中使用比较多。protobuf对于结构中的每个成员,会提供set系列函数和get系列函数。
但是,对于使用来说,需要根据传入的参数考虑需要调用的函数名,在使用这个比较多的情况,还是会让人觉得有些麻烦。而且,对于有些使用,例如之后打算不再使用protobuf,改为直接将数据压入内存段(The raw in-memory data structures sent/saved in binary form),或者直接压入内存段的方式,改为使用protobuf,那么,如果两者都是通过传入函数的方式来进行数据设置,或者数据解析,那么改动内容会比较少,而且出错几率也会比较低。那么如何实现呢?
先给出proto文件:
syntax = "proto2"; package student; message Student
{
required string name = ;
required int32 id = ;
optional int32 age = ;
optional string phoneNumber = ;
}
下面给出通过函数重载方式,来处理各种参数类型的方式:
#include <google\protobuf\message.h> namespace goo_proto = ::google::protobuf; template <typename Param>
struct ProtoFunc
{
static constexpr void* SetValueFunc = nullptr;
}; template <>
struct ProtoFunc<goo_proto::int32>
{
static constexpr auto SetValueFunc = &(goo_proto::Reflection::SetInt32);
}; template <>
struct ProtoFunc<goo_proto::int64>
{
static constexpr auto SetValueFunc = &(goo_proto::Reflection::SetInt64);
}; template <>
struct ProtoFunc<std::string>
{
static constexpr auto SetValueFunc = &(goo_proto::Reflection::SetString);
}; template <>
struct ProtoFunc<const char*>
{
static constexpr auto SetValueFunc = &(goo_proto::Reflection::SetString);
}; template <typename ValueType>
void SetFieldValue(goo_proto::Message* msg, const goo_proto::Reflection* reflection,
const goo_proto::FieldDescriptor* field, ValueType&& value)
{
(reflection->*(ProtoFunc<std::remove_cv_t<std::decay_t<ValueType>>>::SetValueFunc))
(msg, field, std::forward<ValueType>(value));
}
通过上述的模板,就可以调用SetFieldValue来处理int32, int64, std::string和const char*了,这个是实现泛型函数的前期准备。
下面给出一次设置多个参数的方式:
template <typename ...Args>
void SetFieldAllValues(goo_proto::Message* msg, Args&&... args)
{
auto descriptor = msg->GetDescriptor();
auto reflection = msg->GetReflection();
SetFieldImpl<>(msg, descriptor, reflection, std::forward<Args>(args)...);
} template <size_t idx, typename T, typename ...Args>
void SetFieldImpl(goo_proto::Message* msg, const goo_proto::Descriptor* descriptor, const goo_proto::Reflection* reflection,
T&& value, Args&&... args)
{
auto field = descriptor->field(idx);
SetFieldValue(msg, reflection, field, std::forward<T>(value));
SetFieldImpl<idx + >(msg, descriptor, reflection, std::forward<Args>(args)...);
} template <size_t idx>
void SetFieldImpl(goo_proto::Message* msg, const goo_proto::Descriptor* descriptor, const goo_proto::Reflection* reflection)
{
// empty
}
上面就是实现,设置所有proto结构体中元素的方式。多谢protobuf中提供了descriptor::field函数,通过这个函数,我才有办法比较简单的实现通过传入所有的参数(这里没有考虑设置repeat成员),来一次性设置好整个proto结构体对象。下面看一下使用上述函数的一个实例:
#include <iostream>
#include <string>
#include "studentinfo.h"
#include "studentinfo.pb.h" int main(int argc, char* argv[])
{
student::Student s;
SetFieldAllValues(&s, "Jack", , , "");
std::cout << s.name() << std::endl;
std::cout << s.id() << std::endl;
std::cout << s.age() << std::endl;
std::cout << s.phonenumber() << std::endl;
return ;
}
这里只是提供了设置的函数(Set函数),没有提供Get函数,不过根据类似的方式,实现Get函数应该不是很困难,这里就不给出代码了。
google的protobuf简单介绍的更多相关文章
- Google Protocol Buffer 简单介绍
以下内容主要整理自官方文档. 为什么使用 Protocol Buffers .proto文件 Protocol Buffers 语法 编译.proto文件 Protocol Buffers API 枚 ...
- Protobuf的简单介绍、使用和分析
Protobuf的简单介绍.使用和分析 一.protobuf是什么? protobuf(Google Protocol Buffers)是Google提供一个具有高效的协议数据交换格式工具库( ...
- iOS开发拓展篇-XMPP简单介绍
iOS开发拓展篇-XMPP简单介绍 一.即时通讯简单介绍 1.简单说明 即时通讯技术(IM)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双 ...
- WebSocket简单介绍
Java后端WebSocket的Tomcat实现 一.WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSoc ...
- TensorFlow简单介绍和在centos上的安装
##tensorflow简单介绍: TensorFlow™ is an open source software library for numerical computation using dat ...
- SQLite数据库和JPA简单介绍
SQLite数据库和JPA简单介绍 一.SQLite简单使用 SQLite是遵循ACID的关系数据库管理系统,它的处理速度很快,它的设计目标是嵌入式的,只需要几百K的内存就可以了. 1.下载SQLit ...
- Epplus 使用的简单介绍
操作Excel的主要有以下类库: MyXls(http://sourceforge.net/projects/myxls/) Koogra(http://sourceforge.net/project ...
- iOS开发——网络编程OC篇&(一)XMPP简单介绍与准备
XMPP简单介绍与准备 一.即时通讯简单介绍 1.简单说明 即时通讯技术(IM)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈 ...
- com.google.common.eventbus.EventBus介绍
以下内容直接翻译了EventBus的注释: com.google.common.eventbus.EventBus介绍: 首先这个类是线程安全的, 分发事件到监听器,并提供相应的方式让监听器注册它们自 ...
随机推荐
- 记录一个下最近用tensorflow的几个坑
1, softmax_cross_entropy_with_logits 的中的logits=x*w+b,其中w应该是[nfeats,nclass],b是[nclass]是对输出的每个类上logits ...
- C/S与B/S的区别
C/S与B/S的区别 1.区别 1.B/S架构是针对C/S架构缺点进行改进后提出的网络结构模式. B/S结构属于C/S结构,是一种特殊的C/S,因为浏览器只是特殊的客户端. 2.C/S可以使用任何通信 ...
- Mac使用Shell(终端)SSH连接远程服务器
先进入终端 输入:ssh -p 端口号 服务器用户名@ip (例如ssh -p 22 root@119.10.168.63)回车,到这会让你输入yes或者no来确认是否连接,输入yes回车 然后输入在 ...
- 常用 blas 函数
Y=alpha * X +beta*Y template <> void caffe_cpu_axpby<float>(const int N, const float alp ...
- C++解析八-多态
多态多态按字面的意思就是多种形态.当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态.C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数.下面的实例中,基类 Sh ...
- centos安装ruby
下面开始安装Ruby 一.下载Ruby源码包 wget ftp://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.7.tar.gz 二.解压安装Ruby tar zx ...
- 开机出错提示 cpu fan speed error detected
问题:开机跳 cpu fan speed error detected 分析:提示是cpu fan speed 有问题进入 BIOS 设置了好几次仍不行 解决方法: 进入BIOS,BOOT选项卡,将 ...
- Windows----Github环境搭建
关于Github的那点事: 一.下载安装 下载地址: https://git-for-windows.github.io/ 在官方下载完后,安装到Windows Explorer integra ...
- 线性表seqList类及其父类list,模板类
seqList模板类,线性表代码 # include "list.h" //代码清单2-2 顺序表类的定义和实现 // The Definition of seqList temp ...
- redis设置过期时间