C++中将FlatBuffers序列化为JSON

​FlatBuffers是google发布的一个高效的序列化库,最近需要将系统中的flatbuffer的二进制数据转换为JSON以便其他系统使用,发现flatbuffer原生支持与JSON结构之间的转换。

方法一:使用GenerateText()函数

加载schema文件内容构造flatbuffers::Parser解析器,最后通过GenerateText()函数解析为JSON字符串。stackoverflow中有一段代码贴来,示例如下:

复制代码
bool MyFBSchemaWrapper::asJson(std::string& jsonOutput)
{
    //**This is the section I don't like having to do
    std::string schemaFile;
    if (flatbuffers::LoadFile((std::string(getenv("FBS_FILE_PATH")) + "MyFBSchema.fbs").c_str(), false, &schemaFile))
    {
        flatbuffers::Parser parser;
        const char *includePaths[] = { getenv("FBS_FILE_PATH");
        parser.Parse(schemaFile.c_str(), includePaths);
    //**End bad section
        parser.opts.strict_json = true;

        flatbuffers::FlatBufferBuilder fbBuilder;
        auto testItem1 = fbBuilder.CreateString("test1");
        auto testItem2 = fbBuilder.CreateString("test2");

        MyFBSchemaBuilder myBuilder(fbBuilder);

        myBuilder.add_item1(testItem1);
        myBuilder.add_item2(testItem2);
        FinishMyFBSchemaBuffer(fbBuilder, myBuilder.finish());

        auto result = GenerateText(parser, fbBuilder.GetBufferPointer(), &jsonOutput);
        return true;
    }
    return false;
}

其中:Parser和GenerateText都定义在在flatbuferrs/idl.h中,如下:

复制代码
  // Parse the string containing either schema or JSON data, which will
  // populate the SymbolTable's or the FlatBufferBuilder above.
  // include_paths is used to resolve any include statements, and typically
  // should at least include the project path (where you loaded source_ from).
  // include_paths must be nullptr terminated if specified.
  // If include_paths is nullptr, it will attempt to load from the current
  // directory.
  // If the source was loaded from a file and isn't an include file,
  // supply its name in source_filename.
  // All paths specified in this call must be in posix format, if you accept
  // paths from user input, please call PosixPath on them first.
  bool Parse(const char* _source, const char** include_paths = nullptr,
             const char* source_filename = nullptr);

// Generate text (JSON) from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema.
// If ident_step is 0, no indentation will be generated. Additionally,
// if it is less than 0, no linefeeds will be generated either.
// See idl_gen_text.cpp.
// strict_json adds "quotes" around field names if true.
// These functions return nullptr on success, or an error string,
// which may happen if the flatbuffer cannot be encoded in JSON (e.g.,
// it contains non-UTF-8 byte arrays in String values).
extern bool GenerateTextFromTable(const Parser& parser, const void* table,
                                  const std::string& tablename,
                                  std::string* text);
extern const char* GenerateText(const Parser& parser, const void* flatbuffer,
                                std::string* text);
extern const char* GenerateTextFile(const Parser& parser,
                                    const std::string& path,
                                    const std::string& file_name);

方法二:使用FlatBuffers中提供的mini reflection机制

这种方法要加上参数(--reflect-types)重新编译头文件,如:

复制代码
# 将原来的命令(flatc -o ./ -cpp *.fbs)加上--reflect-types
flatc -o ./ --reflect-types -cpp *.fbs

使用FlatBufferToString函数

FlatBufferToString()函数定义在flatbuferrs/minireflect.h中,如下:

复制代码
inline std::string FlatBufferToString(const uint8_t* buffer,
                                      const TypeTable* type_table,
                                      bool multi_line = false,
                                      bool vector_delimited = true,
                                      const std::string& indent = "",
                                      bool quotes = false) {
  ToStringVisitor tostring_visitor(multi_line ? "\n" : " ", quotes, indent,
                                   vector_delimited);
  IterateFlatBuffer(buffer, type_table, &tostring_visitor);
  return tostring_visitor.s;
}

REF.

  1. https://github.com/google/flatbuffers/tree/master
  2. https://stackoverflow.com/questions/60176212/serializing-a-flatbuffer-object-to-json-without-its-schema-file
  3. https://dbaileychess.github.io/flatbuffers/flatbuffers_guide_using_schema_compiler.html
  4. https://flatbuffers.dev/languages/cpp/#mini-reflection
相关推荐
Fruiticecake2 分钟前
C 程序员速通现代 C++(一):lambda、std::function、移动语义与智能指针
c语言·c++
总要学点什么4 分钟前
第98篇:三维特效-材质线效果——给一条线换十种材质,虚线的图案只填了一半
开发语言·前端·javascript·ecmascript·gis·webgl·材质
田甲19 分钟前
做一款 Type-C 母座读卡器:GL3224 双卡方案实测
c语言·开发语言
青少儿编程课堂30 分钟前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:中缀表达式求值解析
c++·python·算法·bfs·信息学竞赛
严肃小白兔36 分钟前
MATLAB 绘图与科研论文插图制作:图形设计、统计表达与矢量导出
开发语言·matlab·科研绘图
Funlang2 小时前
给机器写的 JavaScript 造个笼子
开发语言·javascript·ecmascript
普通人62 小时前
PHP文件读写完全指南
开发语言·php·1024程序员节
坤坤子吖3 小时前
Linux网络编程:TCP服务器的多进程与多线程实现
linux·服务器·开发语言·网络·c++·笔记·学习
一晌小贪欢4 小时前
Python基础:第 09 篇 · while 循环:重复直到不满足
开发语言·c++·python·数据可视化·面向对象·python办公
xiaoye-duck4 小时前
《C++ 项目:手写大模型接入 SDK》LLMManager架构设计与实现
开发语言·网络·c++·语言模型