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介绍: 首先这个类是线程安全的, 分发事件到监听器,并提供相应的方式让监听器注册它们自 ...
随机推荐
- Lua 语言变量
Lua 变量 变量在使用前,必须在代码中进行声明,即创建该变量.编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,用于存储变量的值. Lua 变量有三种类型:全局变量.局部变量.表中的域. ...
- Centos 7 搭建DNS笔记
bindind的程序包 bind-libs:被bind和bind-utils包中的程序共同用到的库文件: bind-utils:bind客户端程序集:提供了,dig , host, nslookup等 ...
- hibernate操作mysql插入修改中文出现乱码
第一步:mysql的安装目录下配置文件my.ini里面的所有default-character-set改成default-character-set = utf8: 第二部:建立数据库时候字符集选项选
- js生成指定范围的随机数
<!doctype html> <html lang="en"> <head> <meta http-equiv="Conten ...
- select 取value值
<md-select ng-model="alarmSelect" style="margin: 0px 0px 0px 0px;" ng-change= ...
- 精确值避免使用float和double,使用BigDecimal
实现将double类型的值转换为BigDecimal类型的值的不同途径以及各途径间的区别 一:有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal ...
- DAY 04运算符与流程控制
输入输出补充: python2与python3的输入输出不同 python2中有两种用户 输入方式,一种是raw_input,和input raw_input与python3的input是相同的 而p ...
- 由一次报错引发的对于Spring创建对象的理解
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ent ...
- webView 获取内容高度不准确的原因是因为你设置了某个属性
不管是UIWebView 还是 WKWebView 这里 获取js属性 获取高度的方法 我就不一一细说了 ,本文最主要不说这个 ,网上有太多的方法 我最不摘几个 CGFloat webViewHeig ...
- Python学习二十八周(vue.js)
一.指令 1.一个例子简单实用vue: 下载vue.js(这里实用1.0.21版本) 编写html代码: <!DOCTYPE html> <html lang="en&qu ...