zoukankan      html  css  js  c++  java
  • Flatbuffers学习

    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 }

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

  • 相关阅读:
    php iconv函数转换出错问题
    linux 上配置swoole
    Linux中查看某 个软件的安装路径
    mysql 5.0存储过程学习总结
    maven--私服的搭建(Nexus的使用)
    Linux的chattr与lsattr命令详解
    [转]Delphi 中 image 控件加载bmp、JPG、GIF、PNG等图片的办法
    [转]Delphi 中动态链接库(dll)的建立和使用
    Delphi PChar与String互转
    [转]Delphi 快捷键 让你更像高手!!
  • 原文地址:https://www.cnblogs.com/jiangyibo/p/14286248.html
Copyright © 2011-2022 走看看