C++ protobuf使用入门实例

清泛原创

protobuf 是结构化数据的系列化/反序列化解决方案,类似XML/JSON,但他的运行效率及压缩率均较后者高一个数量级,且完全的跨平台。使用步骤如下:

1、定义一个.proto数据结构文件,如test.proto:
syntax = "proto3";

package google.protobuf;

option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option cc_enable_arenas = true;
option go_package = "google.golang.org/protobuf/types/known/testpb";
option java_package = "com.google.protobuf";
option java_outer_classname = "TestProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";

// `Test` represents a structured data value, consisting of fields
// which map to dynamically typed values. In some languages, `Test`
// might be supported by a native representation. For example, in
// scripting languages like JS a struct is represented as an
// object. The details of that representation are described together
// with the proto support for the language.
//
// The JSON representation for `Test` is JSON object.
message Test {
  // Unordered map of dynamically typed values.
  map<string, TestValue> fields = 1;
}

// `Value` represents a dynamically typed value which can be either
// null, a number, a string, a boolean, a recursive struct value, or a
// list of values. A producer of value is expected to set one of that
// variants, absence of any variant indicates an error.
//
// The JSON representation for `Value` is JSON value.
message TestValue {
  // The kind of value.
  oneof kind {
    // Represents a null value.
    TestNullValue null_value = 1;
    // Represents a double value.
    double number_value = 2;
    // Represents a string value.
    string string_value = 3;
    // Represents a boolean value.
    bool bool_value = 4;
    // Represents a structured value.
    Test struct_value = 5;
    // Represents a repeated `Value`.
    TestListValue list_value = 6;
  }
}

// `NullValue` is a singleton enumeration to represent the null value for the
// `Value` type union.
//
//  The JSON representation for `NullValue` is JSON `null`.
enum TestNullValue {
  // Null value.
  NULL_VALUE = 0;
}

// `ListValue` is a wrapper around a repeated field of values.
//
// The JSON representation for `ListValue` is JSON array.
message TestListValue {
  // Repeated field of dynamically typed values.
  repeated TestValue values = 1;
}
2、使用protoc命令(自行安装或源码编译)将上述文件编译成各种平台代码,这里以C++为例:
./protoc --cpp_out=. test.proto

执行后,会生成test.pb.h 及 test.pb.cc 两个代码文件,其他语言也会生成相应的代码。
3、添加测试代码测试结构体数据的序列化及反序列化:

/*
 * misc_test.cc
 *
 *  Created on: Jun 27, 2021
 *      Author: root
 */

#include "../my_test.h"
#include "test.pb.h"

TEST(ProtobufTest, PackAndUnpack) {
	// ------Serialize------
	google::protobuf::TestValue msg_val;
	msg_val.set_number_value(123.f);
	std::string str = msg_val.SerializeAsString();
	std::cout << "--------- len:" << str.length() << ":" << str << std::endl;

	google::protobuf::Test message;
	message.mutable_fields()->operator []("test") = msg_val;
	str = message.SerializeAsString();
	std::cout << "--------- len:" << str.length() << ":" << str << std::endl;


	// -------DeSerialize------
	google::protobuf::Test parsed_msg;
	EXPECT_TRUE(parsed_msg.ParseFromString(str));
	EXPECT_EQ(parsed_msg.fields_size(), 1);
	EXPECT_EQ(parsed_msg.fields().begin()->first, "test");
	EXPECT_EQ(parsed_msg.fields().begin()->second.number_value(), 123.f);
}

执行结果:

--------- len:9:(二进制数据打印不了)
--------- len:19:(二进制数据打印不了)

End.

protobuf

分享到:
评论加载中,请稍后...
创APP如搭积木 - 创意无限,梦想即时!
回到顶部