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
相关推荐
老四啊laosi1 天前
[C++进阶] 24. 哈希表封装unordered_map && unordered_set
c++·哈希表·封装·unordered_map·unordered_set
014-code1 天前
订单超时取消与库存回滚的完整实现(延迟任务 + 状态机)
java·开发语言
妙为1 天前
银河麒麟V4下编译Qt5.12.12源码
c++·qt·国产化·osg3.6.5·osgearth3.2·银河麒麟v4
lly2024061 天前
组合模式(Composite Pattern)
开发语言
游乐码1 天前
c#泛型约束
开发语言·c#
Dontla1 天前
go语言Windows安装教程(安装go安装Golang安装)(GOPATH、Go Modules)
开发语言·windows·golang
chushiyunen1 天前
python rest请求、requests
开发语言·python
铁东博客1 天前
Go实现周易大衍筮法三变取爻
开发语言·后端·golang
baidu_huihui1 天前
在 CentOS 9 上安装 pip(Python 的包管理工具)
开发语言·python·pip
南 阳1 天前
Python从入门到精通day63
开发语言·python