c++ - 协议(protocol) buffer3 和 json

标签 c++ json protocol-buffers proto3

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

是否有人使用该功能?

最佳答案

我使用的是 Protobuf 3.3.0,它有一个内置的 JSON 序列化器和解析器。您可以使用 google/protobuf/util/json_util.h 中的 2 个函数,分别称为 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

关于c++ - 协议(protocol) buffer3 和 json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34906305/

相关文章:

javascript - 在 Backbone.js 中使用 toJSON()

java - 无法从文件读回 protobuf

c++ - 如何在我的系统中使用 OpenCL

javascript - 访问未知对象名称中的数据

c++ - 如何重载 >> 运算符以获取可变参数列表

java - java中如何跳过空值元素?

node.js - 从 Google Logging API 解码 protoPayload

android - Google protobuf 在解析字符串数据时在 Android 中崩溃

c++ - 在头文件中定义模板,在派生类中的 cpp 文件中定义

java - 相同的正则表达式搜索结果在 C++ 和 Java 中不同