flatbuffers简介

FlatBuffers 是一个(二进制 buffer)序列化开源库,由 Google 开源现在它支持C++, C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust and Swift等。
 

特点

  1. 无需解析/解包即可访问序列化数据;
  2. 强类型;
  3. 使用方便;
  4. 无依赖的跨平台代码;

与Protocol Buffers的比较(优点):

  使用过程中,我觉得flat对比proto最大的优点就是“零拷贝”反序列化,如果你需要大量的反序列化,flat要比proto更合适一些。
 
 

FlatBuffers schema

 1 #include "FbBasicType.fbs";       // 消息头的类型,时间戳等等
2
3 namespace Jflat;
4
5 table FbFunction{
6 func_id : uint32;
7 param_list : [string]; // vector类型
8 return_value : string;
9 }
10
11 root_type FbFunction; // root_type声明序列化数据的object

FlatBuffers schema compilation

  使用“flatc”编译.fbs文件,它将为对应编程语言创建生成代码。

1 flatc --gen-mutable --gen-object-api --reflect-names --cpp-ptr-type flatbuffers::unique_ptr --gen-compare  --json --cpp --java --js --python *.fbs #--gen-all
2
3 --gen-mutable Generate accessors that can mutate buffers in-place.
4 --gen-object-api Generate an additional object-based API.
5 --reflect-names Add minimal type/name reflection.
6 --gen-compare Generate operator== for object-based API types.

FlatBuffers serialization methods

.h文件

 1 #ifndef JFUNCTION_H
2 #define JFUNCTION_H
3
4 #include "JflatHeader.h"
5
6 class JFunction : public JflatHeader
7 {
8 public:
9
10 uint32_t func_id;
11 std::vector<std::string> param_list;
12 std::string return_value;
13
14 public:
15 JFunction();
16
17 explicit JFunction(const uint8_t *tmp_data);
18
19 explicit JFunction(uint32_t tmp_func_id, std::vector<std::string> &tmp_param_list, const std::string &tmp_return_value);
20
21 JFunction(const JFunction &tmp);
22
23 JFunction &operator=(const JFunction &tmp);
24
25 ~JFunction() = default;
26
27 std::string str();
28
29 const Jflat::FbMessage *getFbMessage(const uint8_t *data);
30
31 flatbuffers::Offset<Jflat::FbFunction> createFbFunction(flatbuffers::FlatBufferBuilder &builder) const;
32
33 flatbuffers::Offset<Jflat::FbMessage> createFbMessage(flatbuffers::FlatBufferBuilder &builder) const override;
34
35 std::shared_ptr<flatbuffers::DetachedBuffer> serializeAsFlat() const;
36
37 bool deserialize(const uint8_t *data) override;
38
39 bool getFbFunction(const Jflat::FbFunction *flat_function);
40
41 std::string serializeAsString() const;
42
43 private:
44 void assignmentVariable(const JFunction &tmp);
45 };
46
47 #endif //JFUNCTION_H

.cpp文件

  1 #include "JFunction.h"
2
3 JFunction::JFunction() : func_id(0),
4 param_list(std::vector<std::string>()),
5 return_value("")
6 {
7 mObjType = Jflat::FbDataHeadType_FBT_RFC;
8 }
9
10 JFunction::JFunction(uint32_t tmp_func_id, std::vector<std::string> &tmp_param_list, const std::string &tmp_return_value)
11 : func_id(tmp_func_id),
12 param_list(tmp_param_list),
13 return_value(tmp_return_value)
14 {
15 mObjType = Jflat::FbDataHeadType_FBT_RFC;
16 }
17
18 JFunction::JFunction(const uint8_t *tmp_data)
19 {
20 mObjType = Jflat::FbDataHeadType_FBT_RFC;
21 deserialize(tmp_data);
22 }
23
24 JFunction::JFunction(const JFunction &tmp)
25 {
26 mObjType = Jflat::FbDataHeadType_FBT_RFC;
27 assignmentVariable(tmp);
28 }
29
30 JFunction &JFunction::operator=(const JFunction &tmp)
31 {
32 if (this != &tmp) assignmentVariable(tmp);
33 return *this;
34 }
35
36 void JFunction::assignmentVariable(const JFunction &tmp)
37 {
38 QObject::assignmentVariable(tmp.mStamp, tmp.mId, tmp.mObjType);
39
40 param_list.assign(tmp.param_list.begin(), tmp.param_list.end());
41 func_id = tmp.func_id;
42 return_value = tmp.return_value;
43 }
44
45 std::string JFunction::str()
46 {
47 return flatbuffers::FlatBufferToString(serializeAsFlat()->data(), Qflat::FbMessageTypeTable(), true);
48 }
49
50 std::string JFunction::serializeAsString() const
51 {
52 auto detached_buffer = serializeAsFlat();
53 if (detached_buffer)
54 return std::string((char *) detached_buffer->data(), detached_buffer->size());
55 else
56 return "";
57 }
58
59 std::shared_ptr<flatbuffers::DetachedBuffer> JFunction::serializeAsFlat() const
60 {
61 flatbuffers::FlatBufferBuilder builder;
62 auto flat = createFbMessage(builder);
63 builder.Finish(flat);
64
65 return std::make_shared<flatbuffers::DetachedBuffer>(builder.Release());
66 }
67
68 const Jflat::FbMessage *JFunction::getFbMessage(const uint8_t *data)
69 {
70 auto data_flat = Jflat::GetFbMessage(data);
71 obj_type = data_flat->header()->type();
72 stamp = data_flat->header()->stamp();
73 id = data_flat->header()->id();
74
75 return data_flat;
76 }
77
78 flatbuffers::Offset<Jflat::FbFunction> JFunction::createFbFunction(flatbuffers::FlatBufferBuilder &builder) const
79 {
80 auto flat_param_list = builder.CreateVectorOfStrings(param_list);
81 auto flat_return_value = builder.CreateString(return_value);
82 auto flat_function = Jflat::CreateFbFunction(builder, func_id, flat_param_list, flat_return_value);
83
84 return flat_function;
85 }
86
87 flatbuffers::Offset<Jflat::FbMessage> JFunction::createFbMessage(flatbuffers::FlatBufferBuilder &builder) const
88 {
89 auto header_function = Jflat::CreateFbMsgHeader(builder, Jflat::FbDataHeadType_FBT_RFC, mStamp, mId);
90 auto flat_function = createFbFunction(builder);
91 auto flat = Jflat::CreateFbMessage(builder, header_function, Jflat::FbMsgBody_FbFunction, flat_function.Union());
92
93 return flat;
94 }
95
96 bool JFunction::deserialize(const uint8_t *data)
97 {
98 auto data_flat = getFbMessage(data);
99 auto flat_function = data_flat->data_as_FbFunction();
100 getFbFunction(flat_function);
101
102 return true;
103 }
104
105 bool JFunction::getFbFunction(const Jflat::FbFunction *flat_function)
106 {
107 func_id = flat_function->func_id();
108
109 param_list.clear();
110 for (const auto &flat_data : *flat_function->param_list())
111 param_list.emplace_back(std::string(flat_data->data(), flat_data->size()));
112
113 return_value = std::string(flat_function->return_value()->data(), flat_function->return_value()->size());
114
115 return true;
116 } 

FlatBuffers example

 1 #include "JFunction.h"
2
3 #include <iostream>
4
5 #define FLAT_DATA_DIFF(before_data, after_data) \
6 { \
7 if(!(before_data == after_data)) \
8 { \
9 std::cout << #before_data << " : line" << __LINE__ << "========================== before =================================" << std::endl; \
10 std::cout << before_data << std::endl; \
11 std::cout << #after_data << " : line" << __LINE__ << "========================== after =================================" << std::endl; \
12 std::cout << after_data << std::endl; \
13 } \
14 }
15
16 void assignment_JFunction_instance(JFunction &jFunction_1)
17 {
18 jFunction_1.func_id = 222;
19
20 for (uint16_t i = 0; i < GENERIC_16_ARRAY_SIZE; ++i)
21 jFunction_1.param_list.push_back(std::to_string(i));
22
23 jFunction_1.return_value = "return_value pi pi sha"; /// 嘿嘿嘿,我女朋友
24 }
25
26 int main(void)
27 {
28 JFunction jFunction_1;
29 assignment_JFunction_instance(jFunction_1);
30 auto buf = jFunction_1.serializeAsFlat();
31
32 JFunction jFunction_2(buf->data());
33
34 FLAT_DATA_DIFF(jFunction_1.str(), jFunction_2.str());
35
36 return 0;
37 }

所有代码仅供参考,记录我当时的应用方法。

Flatbuffers学习的更多相关文章

  1. 值得学习的C语言开源项目

    值得学习的C语言开源项目   - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工 ...

  2. 值得学习的C/C++开源框架(转)

    值得学习的C语言开源项目 - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的 ...

  3. JAVA学习资源整理

    构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...

  4. C++的一些不错开源框架,可以学习和借鉴

    from https://www.cnblogs.com/charlesblc/p/5703557.html [本文系外部转贴,原文地址:http://coolshell.info/c/c++/201 ...

  5. 【C/C++开发】值得学习的C语言开源项目

    值得学习的C语言开源项目 - 1. Webbench Webbench是一个在Linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的 ...

  6. 值得学习的C语言开源项目和库

    收集一些C/C++相关的源码,如有更高效的库,请提醒我 补充上去 C/C++相关交流Q群 1414577 - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具. ...

  7. 值得学习的C/C++开源项目 持续更新

    值得学习的C语言开源项目 持续更新 文章目录 值得学习的C语言开源项目 持续更新 - 1. Webbench - 2. Tinyhttpd - 3. cJSON - 4. CMockery - 5. ...

  8. 金玉良缘易配而木石前盟难得|M1 Mac os(Apple Silicon)天生一对Python3开发环境搭建(集成深度学习框架Tensorflow/Pytorch)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_189 笔者投入M1的怀抱已经有一段时间了,俗话说得好,但闻新人笑,不见旧人哭,Intel mac早已被束之高阁,而M1 mac已经 ...

  9. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

随机推荐

  1. SpringAOP--aop使用

    SpringAOP使用方式 切点表达式 常用的符号: *:匹配任何数量字符: ..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包:而在方法参数模式中匹配任何数量参数. +:匹配指定类型的子类 ...

  2. Grep 命令有什么用?如何忽略大小写?如何查找不含该串的行?

    是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来. grep [stringSTRING] filename grep [^string] filename

  3. 什么时候用断言(assert)?

    答:断言在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制.一般来说,断言用于保证程序最基本.关键的正确性.断言检查通常在开发和测试时开启.为了保证程序的执行效率,在软件发布后断言检查通常 ...

  4. Web,RESTful API 在微服务中的作用是什么?

    微服务架构基于一个概念,其中所有服务应该能够彼此交互以构建业务功能.因 此,要实现这一点,每个微服务必须具有接口.这使得 Web API 成为微服务的一 个非常重要的推动者.RESTful API 基 ...

  5. Mock 或 Stub 有什么区别?

    存根 一个有助于运行测试的虚拟对象. 在某些可以硬编码的条件下提供固定行为. 永远不会测试存根的任何其他行为. 例如,对于空堆栈,您可以创建一个只为 empty()方法返回 true 的存根.因此, ...

  6. Java 中的 LinkedList 是单向链表还是双向链表?

    是双向链表,你可以检查 JDK 的源码.在 Eclipse,你可以使用快捷键 Ctrl + T, 直接在编辑器中打开该类.

  7. Effective Java —— try-with-resources 优先于 try-finally

    本文参考 本篇文章参考自<Effective Java>第三版第九条"Prefer try-with-resources to try-finally" The cod ...

  8. 解决引用类型为什么打出的是地址值,又怎么改成输出属性值(toString()底层)

    一丶toString的源码解析: 一丶object的toString的源码解析: 集合中toString源码分析: 小结: 改成输出属性值 在父类中重写toString();方法 快捷键:Alt+In ...

  9. (stm32f103学习总结)—DS18B20

    一. DS18B20简介 DS18B20数字温度传感器接线方便,封装后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式.主要根据应用场合的不同而改变其外观.封装后的DS18B20可用于电缆 ...

  10. Hadoop 3.1.2报错:xception in thread "main" org.apache.hadoop.fs.UnsupportedFileSystemException: No FileSystem for scheme "hdfs"

    报错内容如下: Exception in thread "main" org.apache.hadoop.fs.UnsupportedFileSystemException: No ...