【问题标题】:Protocol buffer3 and json协议 buffer3 和 json
【发布时间】:2016-04-26 16:02:43
【问题描述】:

Protocol buffer v3 声称,该库对 json 友好 (https://developers.google.com/protocol-buffers/docs/proto3#json),但我找不到如何获得该映射。我应该在 protoc 中添加一些插件或一些选项,还是调用一些特殊的东西来代替 SerializeTo/ParseFrom?

是否有人使用该功能?

【问题讨论】:

    标签: c++ json protocol-buffers proto3


    【解决方案1】:

    我使用的是 Protobuf 3.3.0,它有一个内置的 JSON 序列化器和解析器。您可以使用google/protobuf/util/json_util.h 中的两个函数MessageToJsonString()JsonStringToMessage() 使您的C++ 生成的Message 对象分别往返于JSON。

    这是一个使用它们的简单测试: test-protobuf.proto:

    syntax = "proto3";
    
    message SearchRequest {
      string query = 1;
      int32 page_number = 2;
      int32 result_per_page = 3;
    }
    

    test-protobuf.cpp:

    #include <iostream>
    #include <google/protobuf/util/json_util.h>
    
    #include "test-protobuf.pb.h"
    
    int main()
    {
      std::string json_string;
      SearchRequest sr, sr2;
    
      // Populate sr.
      sr.set_query(std::string("Hello!"));
      sr.set_page_number(1);
      sr.set_result_per_page(10);
    
      // Create a json_string from sr.
      google::protobuf::util::JsonPrintOptions options;
      options.add_whitespace = true;
      options.always_print_primitive_fields = true;
      options.preserve_proto_field_names = true;
      MessageToJsonString(sr, &json_string, options);
    
      // Print json_string.
      std::cout << json_string << std::endl;
    
    
      // Parse the json_string into sr2.
      google::protobuf::util::JsonParseOptions options2;
      JsonStringToMessage(json_string, &sr2, options2);
    
      // Print the values of sr2.
      std::cout
        << sr2.query() << ", "
        << sr2.page_number() << ", "
        << sr2.result_per_page() << std::endl
      ;
    
      return 0;
    }
    

    您可以使用以下CMakeLists.txt 文件(在 Windows 上测试)来编译这些文件(假设您已安装 protobuf、编译器和 CMake)。

    cmake_minimum_required(VERSION 3.8)
    
    project(test-protobuf)
    
    find_package(Protobuf REQUIRED)
    
    # Use static runtime for MSVC
    if(MSVC)
      foreach(flag_var
          CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
          CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
        if(${flag_var} MATCHES "/MD")
          string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
        endif(${flag_var} MATCHES "/MD")
      endforeach(flag_var)
    endif(MSVC)
    
    protobuf_generate_cpp(test-protobuf-sources test-protobuf-headers
      "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.proto"
    )
    
    list(APPEND test-protobuf-sources
      "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.cpp"
    )
    
    add_executable(test-protobuf ${test-protobuf-sources} ${test-protobuf-headers})
    target_include_directories(test-protobuf
      PUBLIC
        ${PROTOBUF_INCLUDE_DIRS}
        ${CMAKE_CURRENT_BINARY_DIR}
    )
    target_link_libraries(test-protobuf
      ${PROTOBUF_LIBRARIES}
    )
    

    假设 CMakeLists.txttest-protobuf.prototest-protobuf.cpp 位于同一目录中,以下是使用 Visual Studio 15 2017 和 64 位 protobuf 库在 Windows 上编译和运行它们的命令。

    mkdir build
    cd build
    cmake -G "Visual Studio 15 2017 Win64" ..
    cmake --build . --config Release
    Release/test-protobuf
    

    您应该会看到以下输出:

    {
     "query": "Hello!",
     "page_number": 1,
     "result_per_page": 10
    }
    
    Hello!, 1, 10
    

    【讨论】:

    • 在 protobuf-C 中是否可以支持 JSON 转换?
    • 真的很好,有什么办法可以用十六进制表示字节值而不是看起来像 base64 的东西?
    【解决方案2】:

    Protobuf 有 C# 的 json api。 google protobuf reference 中有一些 C# 的 json 类,您可以在 github protobuf repository 中找到一些针对 java 和 c++ 的测试。

    【讨论】:

    • 我正在积累使用 Protobuf 和 C# 的经验。 JsonFormatter 只接受 IMessage 作为输入。假设您只有一些 Protobuf 消息实例...如何将其转换为 IMessage 以便可以序列化为 Json?
    • 这是来自 Protobuf -> JSON 的答案: string jsonMessage = Google.Protobuf.JsonFormatter.Default.Format((IMessage)person); .............来自 JSON -> Protobuf: IMessage message = (IMessage)Activator.CreateInstance(typeof(Person));人 personFromJSON = (Person)Google.Protobuf.JsonParser.Default.Parse(jsonMessage, message.Descriptor);
    猜你喜欢
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 2023-04-10
    • 2019-02-08
    相关资源
    最近更新 更多