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介绍: 首先这个类是线程安全的, 分发事件到监听器,并提供相应的方式让监听器注册它们自 ...
随机推荐
- CSS选择器 nth-child 和 nth-of-type
Css 3 中两个新的选择器 nth-child 和 nth-of-type 都可以选择父元素下对应的子元素,但它们到底有什么区别呢? :nth-child(n) 选择器匹配属于其父元素下的第n个子元 ...
- icpc2018-焦作-F Honeycomb bfs
http://codeforces.com/gym/102028/problem/F 就是一个bfs,主要问题是建图,要注意奇数和偶数列的联通方案是略有不同的.比赛的时候写完一直不过样例最后才发现没考 ...
- springboot启动插件
对jsp支持后不再使用启动类启动项目,否则无法支持jsp <plugins> <plugin> <groupId>org.springframework.boot& ...
- java中double和float精度丢失问题及解决方法
在讨论两位double数0.2和0.3相加时,毫无疑问他们相加的结果是0.5.但是问题总是如此吗? 下面我们让下面两个doubles数相加,然后看看输出结果: @Test public void te ...
- css3 二级菜单
<!doctype html><!--<!DOCTYPE> 声明位于文档中的最前面的位置,处于 <html> 标签之前.此标签可告知浏览器文档使用哪种 HTM ...
- day34-python操作redis三
Hash类型操作 Hash类型操作 Redis在内存中存储hash类型是以name对应一个字典形式存储的 hset(name,key,value) #name对应的hash中设置一个键值对(不存在,则 ...
- spring boot 添加客户端负载均衡
1.pom.xml文件中,添加依赖包 <dependency> <groupId>org.springframework.cloud</groupId> <a ...
- xenserver挂载新硬盘
注意:新加硬盘请不要加入raid,否则不认盘 一: 1.1:查看磁盘列表 fdisk -l [root@xenserver zz]# fdisk -l Disk /dev/sdb: 7999.4 GB ...
- Collection集合的三种初始化方法
(一) java容器可以分为两大类 1)Collection其中包括List,Set,Queue 2)Map (二) Arrays.asList()方法:接受一个数组或一个逗号分隔的元素列表,并将其转 ...
- xpath提取到的中文乱码时的解决办法
βҳ转换为正常的中文: