当前位置: 首页 > news >正文

[Protobuf] 快速上手:安全高效的序列化指南

标题:[Protobuf] (1)快速上手
@水墨不写bug


在这里插入图片描述


文章目录

  • 一、什么是protobuf?
  • 二、protobuf的特点
  • 三、使用protobuf的过程?
    • 1、定义消息格式(.proto文件)
      • (1)指定语法版本
      • (2)package 声明符
    • 2、使用protoc编译器生成代码
      • (1)当前目录直接编译:
      • (2)指定目录编译
    • 3、在业务中引入并使用生成的类
    • 4、在网络通信或存储中使用protobuf序列化数据
  • 四、快速上手写一个小需求来熟悉如何编写proto文件?


一、什么是protobuf?

Protocol Buffers(简称 protobuf)是由 Google 开发的一种与语言无关、平台无关、可扩展序列化数据结构的方法。它用于结构化数据的序列化与反序列化,类似于 XMLJSON,但更小、更快、更简单


二、protobuf的特点

protobuf 可以把数据结构(比如对象或消息)编码成紧凑的二进制格式,之后再还原回原始的数据结构。 这说明protobuf编码是比较安全的,因为二进制无法被直接阅读。

其他重要特点:

  • 跨语言(支持 Java、C++、Python、Go、C#、JavaScript 等多种语言)
  • 二进制格式,高效且体积小
  • 向后兼容和向前兼容性好(适合长期演进的系统)
  • 需要提前定义数据结构(.proto 文件)

减少开发周期和负担
protobuf可以通过protoc编译器来编译proto文件来生成对应的头文件和源文件,内部已经实现了序列化和反序列化的接口。- - - 节省开发时间,避免重复性造轮子


三、使用protobuf的过程?

1、定义消息格式(.proto文件)

(1)指定语法版本

创建**.proto**文件后,首行需要先指定protobuf的语法版本,如果不指定,默认使用proto2。一般我们都使用proto3。 - - - proto3的语法更加简便,支持更多的语言(比如C#)

(2)package 声明符

在proto文件编译之后,如果写了pageage声明,那么cc和h文件内部会被命名空间封装。
如果没有package声明,则cc和h文件的对应类不会被命名空间包裹。

2、使用protoc编译器生成代码

经过1、2两步,后,就可以编写消息的内部数据结构了,假如如下设计(文件名称为 “contact.proto” ):

//首行:语法指定行
syntax = "proto3";//package 声明符
package contast;//定义联系人信息
message PersonInfo
{string name = 1;int32 age = 2;
}

下一步就需要编译:

(1)当前目录直接编译:

protoc --cpp_out=. contact.proto

这段指令的含义如下:

  • protoc:表示 Protocol Buffers 的编译器程序(Protocol Compiler)。
  • --cpp_out=.:指定生成 C++ 语言的代码文件,并将生成的文件输出到当前目录(. 代表当前目录)。
  • contact.proto:需要被编译的 proto 文件,即你定义了消息结构的协议文件。

综合解释
这条命令的作用是:
使用 Protocol Buffers 的编译器 protoc,将 contact.proto 文件中定义的消息结构,自动生成对应的 C++ 源代码文件(通常为 contact.pb.hcontact.pb.cc),并把它们输出到当前目录下。

这样你就可以在 C++ 项目中直接包含和使用这些自动生成的代码了。

(2)指定目录编译

这种情况适用于当前没有处在contact.proto文件所在的目录时:

protoc -I contact_dir/ --cpp_out=contact_dir/ contact.proto

这段指令的含义如下:

  • protoc
    Protocol Buffers 的编译器(protocol compiler)。

  • -I contact_dir/
    指定包含 proto 文件的搜索目录(即 import 路径)。表示编译器在 contact_dir/ 目录下查找 proto 文件及其 import 的依赖。

  • --cpp_out=contact_dir/
    指定输出目录contact_dir/,并生成 C++ 源代码(通常为 .pb.h.pb.cc 文件)。

  • contact.proto
    要编译的 proto 文件,定义了具体的数据结构。


综合解释:
这条命令会让 protoccontact_dir/ 目录下查找 contact.proto,将其编译为 C++ 源代码,并把生成的 .pb.h.pb.cc 文件输出到同样的 contact_dir/ 目录下。

这种写法常用于项目结构较复杂时,便于管理 proto 文件及生成的代码。


3、在业务中引入并使用生成的类

通过protoc编译proto文件之后,会生成下面两个文件:

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: contact.proto
// Protobuf C++ Version: 6.31.0#include "contact.pb.h"#include <algorithm>
#include <type_traits>
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/generated_message_tctable_impl.h"
#include "google/protobuf/extension_set.h"
#include "google/protobuf/generated_message_util.h"
#include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/reflection_ops.h"
#include "google/protobuf/wire_format.h"
// @@protoc_insertion_point(includes)// Must be included last.
#include "google/protobuf/port_def.inc"
PROTOBUF_PRAGMA_INIT_SEG
namespace _pb = ::google::protobuf;
namespace _pbi = ::google::protobuf::internal;
namespace _fl = ::google::protobuf::internal::field_layout;
namespace contact {inline constexpr Info::Impl_::Impl_(::_pbi::ConstantInitialized) noexcept: _cached_size_{0},name_(&::google::protobuf::internal::fixed_address_empty_string,::_pbi::ConstantInitialized()),age_{0} {}template <typename>
PROTOBUF_CONSTEXPR Info::Info(::_pbi::ConstantInitialized)
#if defined(PROTOBUF_CUSTOM_VTABLE): ::google::protobuf::Message(Info_class_data_.base()),
#else   // PROTOBUF_CUSTOM_VTABLE: ::google::protobuf::Message(),
#endif  // PROTOBUF_CUSTOM_VTABLE_impl_(::_pbi::ConstantInitialized()) {
}
struct InfoDefaultTypeInternal {PROTOBUF_CONSTEXPR InfoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}~InfoDefaultTypeInternal() {}union {Info _instance;};
};PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINITPROTOBUF_ATTRIBUTE_INIT_PRIORITY1 InfoDefaultTypeInternal _Info_default_instance_;
}  // namespace contact
static constexpr const ::_pb::EnumDescriptor *PROTOBUF_NONNULL *PROTOBUF_NULLABLEfile_level_enum_descriptors_contact_2eproto = nullptr;
static constexpr const ::_pb::ServiceDescriptor *PROTOBUF_NONNULL *PROTOBUF_NULLABLEfile_level_service_descriptors_contact_2eproto = nullptr;
const ::uint32_tTableStruct_contact_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {0x081, // bitmapPROTOBUF_FIELD_OFFSET(::contact::Info, _impl_._has_bits_),5, // hasbit index offsetPROTOBUF_FIELD_OFFSET(::contact::Info, _impl_.name_),PROTOBUF_FIELD_OFFSET(::contact::Info, _impl_.age_),0,1,
};static const ::_pbi::MigrationSchemaschemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {{0, sizeof(::contact::Info)},
};
static const ::_pb::Message* PROTOBUF_NONNULL const file_default_instances[] = {&::contact::_Info_default_instance_._instance,
};
const char descriptor_table_protodef_contact_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {"\n\rcontact.proto\022\007contact\"!\n\004Info\022\014\n\004name""\030\001 \001(\t\022\013\n\003age\030\002 \001(\005b\006proto3"
};
static ::absl::once_flag descriptor_table_contact_2eproto_once;
PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_contact_2eproto = {false,false,67,descriptor_table_protodef_contact_2eproto,"contact.proto",&descriptor_table_contact_2eproto_once,nullptr,0,1,schemas,file_default_instances,TableStruct_contact_2eproto::offsets,file_level_enum_descriptors_contact_2eproto,file_level_service_descriptors_contact_2eproto,
};
namespace contact {
// ===================================================================class Info::_Internal {public:using HasBits =decltype(::std::declval<Info>()._impl_._has_bits_);static constexpr ::int32_t kHasBitsOffset =8 * PROTOBUF_FIELD_OFFSET(Info, _impl_._has_bits_);
};Info::Info(::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
#if defined(PROTOBUF_CUSTOM_VTABLE): ::google::protobuf::Message(arena, Info_class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE: ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLESharedCtor(arena);// @@protoc_insertion_point(arena_constructor:contact.Info)
}
PROTOBUF_NDEBUG_INLINE Info::Impl_::Impl_(::google::protobuf::internal::InternalVisibility visibility,::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,const ::contact::Info& from_msg): _has_bits_{from._has_bits_},_cached_size_{0},name_(arena, from.name_) {}Info::Info(::google::protobuf::Arena* PROTOBUF_NULLABLE arena,const Info& from)
#if defined(PROTOBUF_CUSTOM_VTABLE): ::google::protobuf::Message(arena, Info_class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE: ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLEInfo* const _this = this;(void)_this;_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);_impl_.age_ = from._impl_.age_;// @@protoc_insertion_point(copy_constructor:contact.Info)
}
PROTOBUF_NDEBUG_INLINE Info::Impl_::Impl_(::google::protobuf::internal::InternalVisibility visibility,::google::protobuf::Arena* PROTOBUF_NULLABLE arena): _cached_size_{0},name_(arena) {}inline void Info::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) {new (&_impl_) Impl_(internal_visibility(), arena);_impl_.age_ = {};
}
Info::~Info() {// @@protoc_insertion_point(destructor:contact.Info)SharedDtor(*this);
}
inline void Info::SharedDtor(MessageLite& self) {Info& this_ = static_cast<Info&>(self);this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();ABSL_DCHECK(this_.GetArena() == nullptr);this_._impl_.name_.Destroy();this_._impl_.~Impl_();
}inline void* PROTOBUF_NONNULL Info::PlacementNew_(const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {return ::new (mem) Info(arena);
}
constexpr auto Info::InternalNewImpl_() {return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(Info),alignof(Info));
}
constexpr auto Info::InternalGenerateClassData_() {return ::google::protobuf::internal::ClassDataFull{::google::protobuf::internal::ClassData{&_Info_default_instance_._instance,&_table_.header,nullptr,  // OnDemandRegisterArenaDtornullptr,  // IsInitialized&Info::MergeImpl,::google::protobuf::Message::GetNewImpl<Info>(),
#if defined(PROTOBUF_CUSTOM_VTABLE)&Info::SharedDtor,::google::protobuf::Message::GetClearImpl<Info>(), &Info::ByteSizeLong,&Info::_InternalSerialize,
#endif  // PROTOBUF_CUSTOM_VTABLEPROTOBUF_FIELD_OFFSET(Info, _impl_._cached_size_),false,},&Info::kDescriptorMethods,&descriptor_table_contact_2eproto,nullptr,  // tracker};
}PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const::google::protobuf::internal::ClassDataFull Info_class_data_ =Info::InternalGenerateClassData_();PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
Info::GetClassData() const {::google::protobuf::internal::PrefetchToLocalCache(&Info_class_data_);::google::protobuf::internal::PrefetchToLocalCache(Info_class_data_.tc_table);return Info_class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<1, 2, 0, 25, 2>
Info::_table_ = {{PROTOBUF_FIELD_OFFSET(Info, _impl_._has_bits_),0, // no _extensions_2, 8,  // max_field_number, fast_idx_maskoffsetof(decltype(_table_), field_lookup_table),4294967292,  // skipmapoffsetof(decltype(_table_), field_entries),2,  // num_field_entries0,  // num_aux_entriesoffsetof(decltype(_table_), field_names),  // no aux_entriesInfo_class_data_.base(),nullptr,  // post_loop_handler::_pbi::TcParser::GenericFallback,  // fallback#ifdef PROTOBUF_PREFETCH_PARSE_TABLE::_pbi::TcParser::GetTable<::contact::Info>(),  // to_prefetch#endif  // PROTOBUF_PREFETCH_PARSE_TABLE}, {{// int32 age = 2;{::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(Info, _impl_.age_), 1>(),{16, 1, 0, PROTOBUF_FIELD_OFFSET(Info, _impl_.age_)}},// string name = 1;{::_pbi::TcParser::FastUS1,{10, 0, 0, PROTOBUF_FIELD_OFFSET(Info, _impl_.name_)}},}}, {{65535, 65535}}, {{// string name = 1;{PROTOBUF_FIELD_OFFSET(Info, _impl_.name_), _Internal::kHasBitsOffset + 0, 0,(0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)},// int32 age = 2;{PROTOBUF_FIELD_OFFSET(Info, _impl_.age_), _Internal::kHasBitsOffset + 1, 0,(0 | ::_fl::kFcOptional | ::_fl::kInt32)},}},// no aux_entries{{"\14\4\0\0\0\0\0\0""contact.Info""name"}},
};
PROTOBUF_NOINLINE void Info::Clear() {
// @@protoc_insertion_point(message_clear_start:contact.Info)::google::protobuf::internal::TSanWrite(&_impl_);::uint32_t cached_has_bits = 0;// Prevent compiler warnings about cached_has_bits being unused(void) cached_has_bits;cached_has_bits = _impl_._has_bits_[0];if ((cached_has_bits & 0x00000001u) != 0) {_impl_.name_.ClearNonDefaultToEmpty();}_impl_.age_ = 0;_impl_._has_bits_.Clear();_internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}#if defined(PROTOBUF_CUSTOM_VTABLE)
::uint8_t* PROTOBUF_NONNULL Info::_InternalSerialize(const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target,::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) {const Info& this_ = static_cast<const Info&>(base);
#else   // PROTOBUF_CUSTOM_VTABLE
::uint8_t* PROTOBUF_NONNULL Info::_InternalSerialize(::uint8_t* PROTOBUF_NONNULL target,::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {const Info& this_ = *this;
#endif  // PROTOBUF_CUSTOM_VTABLE// @@protoc_insertion_point(serialize_to_array_start:contact.Info)::uint32_t cached_has_bits = 0;(void)cached_has_bits;// string name = 1;if ((this_._impl_._has_bits_[0] & 0x00000001u) != 0) {if (!this_._internal_name().empty()) {const ::std::string& _s = this_._internal_name();::google::protobuf::internal::WireFormatLite::VerifyUtf8String(_s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "contact.Info.name");target = stream->WriteStringMaybeAliased(1, _s, target);}}// int32 age = 2;if ((this_._impl_._has_bits_[0] & 0x00000002u) != 0) {if (this_._internal_age() != 0) {target =::google::protobuf::internal::WireFormatLite::WriteInt32ToArrayWithField<2>(stream, this_._internal_age(), target);}}if (ABSL_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) {target =::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);}// @@protoc_insertion_point(serialize_to_array_end:contact.Info)return target;
}#if defined(PROTOBUF_CUSTOM_VTABLE)
::size_t Info::ByteSizeLong(const MessageLite& base) {const Info& this_ = static_cast<const Info&>(base);
#else   // PROTOBUF_CUSTOM_VTABLE
::size_t Info::ByteSizeLong() const {const Info& this_ = *this;
#endif  // PROTOBUF_CUSTOM_VTABLE// @@protoc_insertion_point(message_byte_size_start:contact.Info)::size_t total_size = 0;::uint32_t cached_has_bits = 0;// Prevent compiler warnings about cached_has_bits being unused(void)cached_has_bits;::_pbi::Prefetch5LinesFrom7Lines(&this_);cached_has_bits = this_._impl_._has_bits_[0];if ((cached_has_bits & 0x00000003u) != 0) {// string name = 1;if ((cached_has_bits & 0x00000001u) != 0) {if (!this_._internal_name().empty()) {total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(this_._internal_name());}}// int32 age = 2;if ((cached_has_bits & 0x00000002u) != 0) {if (this_._internal_age() != 0) {total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(this_._internal_age());}}}return this_.MaybeComputeUnknownFieldsSize(total_size,&this_._impl_._cached_size_);
}void Info::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) {auto* const _this = static_cast<Info*>(&to_msg);auto& from = static_cast<const Info&>(from_msg);// @@protoc_insertion_point(class_specific_merge_from_start:contact.Info)ABSL_DCHECK_NE(&from, _this);::uint32_t cached_has_bits = 0;(void) cached_has_bits;cached_has_bits = from._impl_._has_bits_[0];if ((cached_has_bits & 0x00000003u) != 0) {if ((cached_has_bits & 0x00000001u) != 0) {if (!from._internal_name().empty()) {_this->_internal_set_name(from._internal_name());} else {if (_this->_impl_.name_.IsDefault()) {_this->_internal_set_name("");}}}if ((cached_has_bits & 0x00000002u) != 0) {if (from._internal_age() != 0) {_this->_impl_.age_ = from._impl_.age_;}}}_this->_impl_._has_bits_[0] |= cached_has_bits;_this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}void Info::CopyFrom(const Info& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:contact.Info)if (&from == this) return;Clear();MergeFrom(from);
}void Info::InternalSwap(Info* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) {using ::std::swap;auto* arena = GetArena();ABSL_DCHECK_EQ(arena, other->GetArena());_internal_metadata_.InternalSwap(&other->_internal_metadata_);swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena);swap(_impl_.age_, other->_impl_.age_);
}::google::protobuf::Metadata Info::GetMetadata() const {return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
// @@protoc_insertion_point(namespace_scope)
}  // namespace contact
namespace google {
namespace protobuf {
}  // namespace protobuf
}  // namespace google
// @@protoc_insertion_point(global_scope)
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::std::false_type_static_init2_ [[maybe_unused]] =(::_pbi::AddDescriptors(&descriptor_table_contact_2eproto),::std::false_type{});
#include "google/protobuf/port_undef.inc"
// Generated by the protocol buffer compiler.  DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: contact.proto
// Protobuf C++ Version: 6.31.0#ifndef contact_2eproto_2epb_2eh
#define contact_2eproto_2epb_2eh#include <limits>
#include <string>
#include <type_traits>
#include <utility>#include "google/protobuf/runtime_version.h"
#if PROTOBUF_VERSION != 6031000
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
#endif
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/arena.h"
#include "google/protobuf/arenastring.h"
#include "google/protobuf/generated_message_tctable_decl.h"
#include "google/protobuf/generated_message_util.h"
#include "google/protobuf/metadata_lite.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/message.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/repeated_field.h"  // IWYU pragma: export
#include "google/protobuf/extension_set.h"  // IWYU pragma: export
#include "google/protobuf/unknown_field_set.h"
// @@protoc_insertion_point(includes)// Must be included last.
#include "google/protobuf/port_def.inc"#define PROTOBUF_INTERNAL_EXPORT_contact_2eprotonamespace google {
namespace protobuf {
namespace internal {
template <typename T>
::absl::string_view GetAnyMessageName();
}  // namespace internal
}  // namespace protobuf
}  // namespace google// Internal implementation detail -- do not use these members.
struct TableStruct_contact_2eproto {static const ::uint32_t offsets[];
};
extern "C" {
extern const ::google::protobuf::internal::DescriptorTable descriptor_table_contact_2eproto;
}  // extern "C"
namespace contact {
class Info;
struct InfoDefaultTypeInternal;
extern InfoDefaultTypeInternal _Info_default_instance_;
extern const ::google::protobuf::internal::ClassDataFull Info_class_data_;
}  // namespace contact
namespace google {
namespace protobuf {
}  // namespace protobuf
}  // namespace googlenamespace contact {// ===================================================================// -------------------------------------------------------------------class Info final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:contact.Info) */ {public:inline Info() : Info(nullptr) {}~Info() PROTOBUF_FINAL;#if defined(PROTOBUF_CUSTOM_VTABLE)void operator delete(Info* PROTOBUF_NONNULL msg, std::destroying_delete_t) {SharedDtor(*msg);::google::protobuf::internal::SizedDelete(msg, sizeof(Info));}
#endiftemplate <typename = void>explicit PROTOBUF_CONSTEXPR Info(::google::protobuf::internal::ConstantInitialized);inline Info(const Info& from) : Info(nullptr, from) {}inline Info(Info&& from) noexcept: Info(nullptr, ::std::move(from)) {}inline Info& operator=(const Info& from) {CopyFrom(from);return *this;}inline Info& operator=(Info&& from) noexcept {if (this == &from) return *this;if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {InternalSwap(&from);} else {CopyFrom(from);}return *this;}inline const ::google::protobuf::UnknownFieldSet& unknown_fields() constABSL_ATTRIBUTE_LIFETIME_BOUND {return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);}inline ::google::protobuf::UnknownFieldSet* PROTOBUF_NONNULL mutable_unknown_fields()ABSL_ATTRIBUTE_LIFETIME_BOUND {return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();}static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {return GetDescriptor();}static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL GetDescriptor() {return default_instance().GetMetadata().descriptor;}static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {return default_instance().GetMetadata().reflection;}static const Info& default_instance() {return *reinterpret_cast<const Info*>(&_Info_default_instance_);}static constexpr int kIndexInFileMessages = 0;friend void swap(Info& a, Info& b) { a.Swap(&b); }inline void Swap(Info* PROTOBUF_NONNULL other) {if (other == this) return;if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {InternalSwap(other);} else {::google::protobuf::internal::GenericSwap(this, other);}}void UnsafeArenaSwap(Info* PROTOBUF_NONNULL other) {if (other == this) return;ABSL_DCHECK(GetArena() == other->GetArena());InternalSwap(other);}// implements Message ----------------------------------------------Info* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {return ::google::protobuf::Message::DefaultConstruct<Info>(arena);}using ::google::protobuf::Message::CopyFrom;void CopyFrom(const Info& from);using ::google::protobuf::Message::MergeFrom;void MergeFrom(const Info& from) { Info::MergeImpl(*this, from); }private:static void MergeImpl(::google::protobuf::MessageLite& to_msg,const ::google::protobuf::MessageLite& from_msg);public:bool IsInitialized() const {return true;}ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;#if defined(PROTOBUF_CUSTOM_VTABLE)private:static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);public:::size_t ByteSizeLong() const { return ByteSizeLong(*this); }::uint8_t* PROTOBUF_NONNULL _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target,::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {return _InternalSerialize(*this, target, stream);}#else   // PROTOBUF_CUSTOM_VTABLE::size_t ByteSizeLong() const final;::uint8_t* PROTOBUF_NONNULL _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target,::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;#endif  // PROTOBUF_CUSTOM_VTABLEint GetCachedSize() const { return _impl_._cached_size_.Get(); }private:void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);static void SharedDtor(MessageLite& self);void InternalSwap(Info* PROTOBUF_NONNULL other);private:template <typename T>friend ::absl::string_view(::google::protobuf::internal::GetAnyMessageName)();static ::absl::string_view FullMessageName() { return "contact.Info"; }protected:explicit Info(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);Info(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Info& from);Info(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, Info&& from) noexcept: Info(arena) {*this = ::std::move(from);}const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;static void* PROTOBUF_NONNULL PlacementNew_(const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,::google::protobuf::Arena* PROTOBUF_NULLABLE arena);static constexpr auto InternalNewImpl_();public:static constexpr auto InternalGenerateClassData_();::google::protobuf::Metadata GetMetadata() const;// nested types ----------------------------------------------------// accessors -------------------------------------------------------enum : int {kNameFieldNumber = 1,kAgeFieldNumber = 2,};// string name = 1;void clear_name() ;const ::std::string& name() const;template <typename Arg_ = const ::std::string&, typename... Args_>void set_name(Arg_&& arg, Args_... args);::std::string* PROTOBUF_NONNULL mutable_name();[[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_name();void set_allocated_name(::std::string* PROTOBUF_NULLABLE value);private:const ::std::string& _internal_name() const;PROTOBUF_ALWAYS_INLINE void _internal_set_name(const ::std::string& value);::std::string* PROTOBUF_NONNULL _internal_mutable_name();public:// int32 age = 2;void clear_age() ;::int32_t age() const;void set_age(::int32_t value);private:::int32_t _internal_age() const;void _internal_set_age(::int32_t value);public:// @@protoc_insertion_point(class_scope:contact.Info)private:class _Internal;friend class ::google::protobuf::internal::TcParser;static const ::google::protobuf::internal::TcParseTable<1, 2,0, 25,2>_table_;friend class ::google::protobuf::MessageLite;friend class ::google::protobuf::Arena;template <typename T>friend class ::google::protobuf::Arena::InternalHelper;using InternalArenaConstructable_ = void;using DestructorSkippable_ = void;struct Impl_ {inline explicit constexpr Impl_(::google::protobuf::internal::ConstantInitialized) noexcept;inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,::google::protobuf::Arena* PROTOBUF_NULLABLE arena);inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,const Info& from_msg);::google::protobuf::internal::HasBits<1> _has_bits_;::google::protobuf::internal::CachedSize _cached_size_;::google::protobuf::internal::ArenaStringPtr name_;::int32_t age_;PROTOBUF_TSAN_DECLARE_MEMBER};union { Impl_ _impl_; };friend struct ::TableStruct_contact_2eproto;
};extern const ::google::protobuf::internal::ClassDataFull Info_class_data_;// ===================================================================// ===================================================================#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// -------------------------------------------------------------------// Info// string name = 1;
inline void Info::clear_name() {::google::protobuf::internal::TSanWrite(&_impl_);_impl_.name_.ClearToEmpty();_impl_._has_bits_[0] &= ~0x00000001u;
}
inline const ::std::string& Info::name() constABSL_ATTRIBUTE_LIFETIME_BOUND {// @@protoc_insertion_point(field_get:contact.Info.name)return _internal_name();
}
template <typename Arg_, typename... Args_>
PROTOBUF_ALWAYS_INLINE void Info::set_name(Arg_&& arg, Args_... args) {::google::protobuf::internal::TSanWrite(&_impl_);_impl_._has_bits_[0] |= 0x00000001u;_impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());// @@protoc_insertion_point(field_set:contact.Info.name)
}
inline ::std::string* PROTOBUF_NONNULL Info::mutable_name()ABSL_ATTRIBUTE_LIFETIME_BOUND {::std::string* _s = _internal_mutable_name();// @@protoc_insertion_point(field_mutable:contact.Info.name)return _s;
}
inline const ::std::string& Info::_internal_name() const {::google::protobuf::internal::TSanRead(&_impl_);return _impl_.name_.Get();
}
inline void Info::_internal_set_name(const ::std::string& value) {::google::protobuf::internal::TSanWrite(&_impl_);_impl_._has_bits_[0] |= 0x00000001u;_impl_.name_.Set(value, GetArena());
}
inline ::std::string* PROTOBUF_NONNULL Info::_internal_mutable_name() {::google::protobuf::internal::TSanWrite(&_impl_);_impl_._has_bits_[0] |= 0x00000001u;return _impl_.name_.Mutable( GetArena());
}
inline ::std::string* PROTOBUF_NULLABLE Info::release_name() {::google::protobuf::internal::TSanWrite(&_impl_);// @@protoc_insertion_point(field_release:contact.Info.name)if ((_impl_._has_bits_[0] & 0x00000001u) == 0) {return nullptr;}_impl_._has_bits_[0] &= ~0x00000001u;auto* released = _impl_.name_.Release();if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) {_impl_.name_.Set("", GetArena());}return released;
}
inline void Info::set_allocated_name(::std::string* PROTOBUF_NULLABLE value) {::google::protobuf::internal::TSanWrite(&_impl_);if (value != nullptr) {_impl_._has_bits_[0] |= 0x00000001u;} else {_impl_._has_bits_[0] &= ~0x00000001u;}_impl_.name_.SetAllocated(value, GetArena());if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.name_.IsDefault()) {_impl_.name_.Set("", GetArena());}// @@protoc_insertion_point(field_set_allocated:contact.Info.name)
}// int32 age = 2;
inline void Info::clear_age() {::google::protobuf::internal::TSanWrite(&_impl_);_impl_.age_ = 0;_impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::int32_t Info::age() const {// @@protoc_insertion_point(field_get:contact.Info.age)return _internal_age();
}
inline void Info::set_age(::int32_t value) {_internal_set_age(value);_impl_._has_bits_[0] |= 0x00000002u;// @@protoc_insertion_point(field_set:contact.Info.age)
}
inline ::int32_t Info::_internal_age() const {::google::protobuf::internal::TSanRead(&_impl_);return _impl_.age_;
}
inline void Info::_internal_set_age(::int32_t value) {::google::protobuf::internal::TSanWrite(&_impl_);_impl_.age_ = value;
}#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif  // __GNUC__// @@protoc_insertion_point(namespace_scope)
}  // namespace contact// @@protoc_insertion_point(global_scope)#include "google/protobuf/port_undef.inc"#endif  // contact_2eproto_2epb_2eh

假如在main函数中需要对PersonInfo类进行使用,需要包含生成的头文件,此外在编译的时候,还需要指定使用-std=c++11选项以及编译连接库 -lprotobuf。

示例:

#include<iostream>
#include"contact.pb.h"
#include<string>
using std::endl;
using std::cout;
using std::cerr;
int main()
{std::string people_str;{contact::PersonInfo info1;info1.set_age(21);info1.set_name("张三");if(!info1.SerializeToString(&people_str)){cerr<<"序列化失败"<<endl;exit(-1);}        cout<<"序列化成功"<<endl;cout<<"people_str:"<<people_str<<endl;cout<<"---------------------------------"<<endl;}{contact::PersonInfo info1;if(!info1.ParseFromString(people_str)){cerr<<"反序列化失败"<<endl;exit(-1);}        cout<<"反序列化成功"<<endl;cout<<"name:"<<info1.name()<<endl;cout<<"age:"<<info1.age()<<endl;}return 0;
}

运行结果:
在这里插入图片描述

4、在网络通信或存储中使用protobuf序列化数据

和本地是相同的,这里不再演示,在后面的讲解和实际项目中再详细展示。


四、快速上手写一个小需求来熟悉如何编写proto文件?

需求: 我们正在开发一个简单的图书管理系统。需要在客户端和服务器之间传输图书信息。每本图书包含以下内容:

  • 图书ID(整数)
  • 书名(字符串)
  • 作者(字符串)
  • 出版年份(整数,可选)
  • 是否借出(布尔值)
  • 借阅人(字符串,可选,仅在借出时填写)

请根据这个需求,设计一个合适的proto文件。


比较完善的答案如下:

//声明语法版本
syntax = "proto3";package books;// 单本图书信息
message Book {int64 id = 1;                  // 图书IDstring title = 2;              // 书名string author = 3;             // 作者int32 year = 4;                // 出版年份(可选,未知为0)bool is_borrowed = 5;          // 是否借出string borrower = 6;           // 借阅人(仅借出时填写,否则为空字符串)
}

完~
在这里插入图片描述

未经作者同意禁止转载

http://www.xdnf.cn/news/638965.html

相关文章:

  • SymAgent:一种用于知识图谱复杂推理的神经符号自学Agent框架
  • Oracle中的[行转列]与[列转行]
  • 【目标检测】【医学图像目标检测】BGF-YOLO:脑肿瘤检测的多尺度注意力特征融合
  • 【linux】systemctl基本语法
  • 康佳Java开发面试题及参考答案
  • 前端vue3实现图片懒加载
  • 【LCEL深度解析】LangChain表达式语言的工程化实践指南
  • 基于stm32单片机的智能盲杖研究
  • # YOLO11解决方案之区域追踪探索
  • Python 数据类型方法(1)
  • Docker 一键部署倒计时页面:Easy Countdown全设备通用
  • 2025年5月18日蓝桥stema省选拔赛答案解析
  • GDB调试工具详解
  • 探索高效视频下载:一款绿色版工具的实用体验
  • FreeRTOSConfig.h的作用
  • Three.js 海量模型加载性能优化指南
  • CMake指令:find_package()在Qt中的应用
  • C# 深入理解类(索引器)
  • Disruptor—3.核心源码实现分析一
  • 黑马点评-分布式锁Lua脚本
  • 在线热更新 Upstream全面掌握 ngx_http_upstream_conf_module
  • 华为OD机试真题——字符串加密 (2025B卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
  • HTTP 和 HTTPS 的区别
  • 量子力学:量子力学为什么不属于经典物理学的范畴?
  • 【面板数据】上市公司外资持股数据集(2005-2023年)
  • 临床研究统计分析核心概念解析
  • 【MATLAB代码】主动声纳多路径目标测距与定位,测距使用互相关,频率、采样率可调、声速可调,定位使用三边法|订阅专栏后可直接查看源代码
  • C++学习之STL学习:string类常用接口的模拟实现
  • 大语言模型的完整训练周期从0到1的体系化拆解
  • 基于Qt的app开发第十一天