如何将嵌套的 Protobuf 消息的值分配给主消息?C++



我正在摆弄Protobuf,试图将c++数据转换为c#,然后在Unity中使用指定的数据。考虑到Unity使用了GameObjects(游戏邦注:例如球体),同时拥有位置数据和缩放数据,我想我会尝试在Protobuf消息中使用这种格式。这会导致消息看起来像这样:

syntax = "proto3";
package Sphere;
message Sphere {

message Position {
float x = 1;
float y = 2;
float z = 3;
}
message Scale {
float x = 1;
float y = 2;
float z = 3;
}
}
message Spheres {
repeated Sphere spheres = 1;
}

现在我的问题是如何将位置和缩放值附加到c++文件中的球体对象。

目前我的c++文件是这样的:

#include <fstream>
#include "sphere.pb.h"
using std::fstream;
Sphere::Sphere sphere1, sphere2;
Sphere::Spheres sphereCollection;
int main() {
using namespace Sphere;
std::fstream sphereData("./Assets/Scripts/sphereData.dat", std::ios::binary|std::ios::out);
Sphere_Position* position1;
position1->set_x(5);
position1->set_y(5);
position1->set_z(5);
Sphere_Scale* scale1;
scale1->set_x(5);
scale1->set_y(5);
scale1->set_z(5);
Sphere_Position* position2;
position2->set_x(5);
position2->set_y(5);
position2->set_z(5);
Sphere_Scale* scale2;
scale2->set_x(5);
scale2->set_y(5);
scale2->set_z(5);

sphereCollection.add_spheres()->CopyFrom(sphere1);
sphereCollection.add_spheres()->CopyFrom(sphere2);
sphereCollection.SerializeToOstream(&sphereData);
return EXIT_SUCCESS;
}

我认为应该有某种方式我可以使用CopyFrom函数从Sphere_Position和Sphere_Scale获取数据,但是我找不到CopyFrom函数可以使用的函数。我确实重新定位了Position和Scale消息,将其包含在Sphere消息中,并在之后重新编译了c++生成的类,尽管我不知道这是否值得做一个更改。

请注意,我的c++知识还不是很清楚,Protobuf也是一样,尽管我已经广泛地查看了谷歌的指南。(当然,这并不排除我错过了什么东西的可能性)

编辑:

这是球体。pb.h:

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: sphere.proto
#ifndef PROTOBUF_INCLUDED_sphere_2eproto
#define PROTOBUF_INCLUDED_sphere_2eproto
#include <string>
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 3006001
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers.  Please update
#error your headers.
#endif
#if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers.  Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/inlined_string_field.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/message.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)
#define PROTOBUF_INTERNAL_EXPORT_protobuf_sphere_2eproto 
namespace protobuf_sphere_2eproto {
// Internal implementation detail -- do not use these members.
struct TableStruct {
static const ::google::protobuf::internal::ParseTableField entries[];
static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
static const ::google::protobuf::internal::ParseTable schema[4];
static const ::google::protobuf::internal::FieldMetadata field_metadata[];
static const ::google::protobuf::internal::SerializationTable serialization_table[];
static const ::google::protobuf::uint32 offsets[];
};
void AddDescriptors();
}  // namespace protobuf_sphere_2eproto
namespace Sphere {
class Sphere;
class SphereDefaultTypeInternal;
extern SphereDefaultTypeInternal _Sphere_default_instance_;
class Sphere_Position;
class Sphere_PositionDefaultTypeInternal;
extern Sphere_PositionDefaultTypeInternal _Sphere_Position_default_instance_;
class Sphere_Scale;
class Sphere_ScaleDefaultTypeInternal;
extern Sphere_ScaleDefaultTypeInternal _Sphere_Scale_default_instance_;
class Spheres;
class SpheresDefaultTypeInternal;
extern SpheresDefaultTypeInternal _Spheres_default_instance_;
}  // namespace Sphere
namespace google {
namespace protobuf {
template<> ::Sphere::Sphere* Arena::CreateMaybeMessage<::Sphere::Sphere>(Arena*);
template<> ::Sphere::Sphere_Position* Arena::CreateMaybeMessage<::Sphere::Sphere_Position>(Arena*);
template<> ::Sphere::Sphere_Scale* Arena::CreateMaybeMessage<::Sphere::Sphere_Scale>(Arena*);
template<> ::Sphere::Spheres* Arena::CreateMaybeMessage<::Sphere::Spheres>(Arena*);
}  // namespace protobuf
}  // namespace google
namespace Sphere {
// ===================================================================
class Sphere_Position : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Sphere.Sphere.Position) */ {
public:
Sphere_Position();
virtual ~Sphere_Position();
Sphere_Position(const Sphere_Position& from);
inline Sphere_Position& operator=(const Sphere_Position& from) {
CopyFrom(from);
return *this;
}
#if LANG_CXX11
Sphere_Position(Sphere_Position&& from) noexcept
: Sphere_Position() {
*this = ::std::move(from);
}
inline Sphere_Position& operator=(Sphere_Position&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
#endif
static const ::google::protobuf::Descriptor* descriptor();
static const Sphere_Position& default_instance();
static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
static inline const Sphere_Position* internal_default_instance() {
return reinterpret_cast<const Sphere_Position*>(
&_Sphere_Position_default_instance_);
}
static constexpr int kIndexInFileMessages =
0;
void Swap(Sphere_Position* other);
friend void swap(Sphere_Position& a, Sphere_Position& b) {
a.Swap(&b);
}
// implements Message ----------------------------------------------
inline Sphere_Position* New() const final {
return CreateMaybeMessage<Sphere_Position>(NULL);
}
Sphere_Position* New(::google::protobuf::Arena* arena) const final {
return CreateMaybeMessage<Sphere_Position>(arena);
}
void CopyFrom(const ::google::protobuf::Message& from) final;
void MergeFrom(const ::google::protobuf::Message& from) final;
void CopyFrom(const Sphere_Position& from);
void MergeFrom(const Sphere_Position& from);
void Clear() final;
bool IsInitialized() const final;
size_t ByteSizeLong() const final;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const final;
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const final;
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Sphere_Position* other);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return NULL;
}
inline void* MaybeArenaPtr() const {
return NULL;
}
public:
::google::protobuf::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
// float x = 1;
void clear_x();
static const int kXFieldNumber = 1;
float x() const;
void set_x(float value);
// float y = 2;
void clear_y();
static const int kYFieldNumber = 2;
float y() const;
void set_y(float value);
// float z = 3;
void clear_z();
static const int kZFieldNumber = 3;
float z() const;
void set_z(float value);
// @@protoc_insertion_point(class_scope:Sphere.Sphere.Position)
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
float x_;
float y_;
float z_;
mutable ::google::protobuf::internal::CachedSize _cached_size_;
friend struct ::protobuf_sphere_2eproto::TableStruct;
};
// -------------------------------------------------------------------
class Sphere_Scale : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Sphere.Sphere.Scale) */ {
public:
Sphere_Scale();
virtual ~Sphere_Scale();
Sphere_Scale(const Sphere_Scale& from);
inline Sphere_Scale& operator=(const Sphere_Scale& from) {
CopyFrom(from);
return *this;
}
#if LANG_CXX11
Sphere_Scale(Sphere_Scale&& from) noexcept
: Sphere_Scale() {
*this = ::std::move(from);
}
inline Sphere_Scale& operator=(Sphere_Scale&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
#endif
static const ::google::protobuf::Descriptor* descriptor();
static const Sphere_Scale& default_instance();
static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
static inline const Sphere_Scale* internal_default_instance() {
return reinterpret_cast<const Sphere_Scale*>(
&_Sphere_Scale_default_instance_);
}
static constexpr int kIndexInFileMessages =
1;
void Swap(Sphere_Scale* other);
friend void swap(Sphere_Scale& a, Sphere_Scale& b) {
a.Swap(&b);
}
// implements Message ----------------------------------------------
inline Sphere_Scale* New() const final {
return CreateMaybeMessage<Sphere_Scale>(NULL);
}
Sphere_Scale* New(::google::protobuf::Arena* arena) const final {
return CreateMaybeMessage<Sphere_Scale>(arena);
}
void CopyFrom(const ::google::protobuf::Message& from) final;
void MergeFrom(const ::google::protobuf::Message& from) final;
void CopyFrom(const Sphere_Scale& from);
void MergeFrom(const Sphere_Scale& from);
void Clear() final;
bool IsInitialized() const final;
size_t ByteSizeLong() const final;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const final;
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const final;
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Sphere_Scale* other);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return NULL;
}
inline void* MaybeArenaPtr() const {
return NULL;
}
public:
::google::protobuf::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
// float x = 1;
void clear_x();
static const int kXFieldNumber = 1;
float x() const;
void set_x(float value);
// float y = 2;
void clear_y();
static const int kYFieldNumber = 2;
float y() const;
void set_y(float value);
// float z = 3;
void clear_z();
static const int kZFieldNumber = 3;
float z() const;
void set_z(float value);
// @@protoc_insertion_point(class_scope:Sphere.Sphere.Scale)
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
float x_;
float y_;
float z_;
mutable ::google::protobuf::internal::CachedSize _cached_size_;
friend struct ::protobuf_sphere_2eproto::TableStruct;
};
// -------------------------------------------------------------------
class Sphere : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Sphere.Sphere) */ {
public:
Sphere();
virtual ~Sphere();
Sphere(const Sphere& from);
inline Sphere& operator=(const Sphere& from) {
CopyFrom(from);
return *this;
}
#if LANG_CXX11
Sphere(Sphere&& from) noexcept
: Sphere() {
*this = ::std::move(from);
}
inline Sphere& operator=(Sphere&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
#endif
static const ::google::protobuf::Descriptor* descriptor();
static const Sphere& default_instance();
static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
static inline const Sphere* internal_default_instance() {
return reinterpret_cast<const Sphere*>(
&_Sphere_default_instance_);
}
static constexpr int kIndexInFileMessages =
2;
void Swap(Sphere* other);
friend void swap(Sphere& a, Sphere& b) {
a.Swap(&b);
}
// implements Message ----------------------------------------------
inline Sphere* New() const final {
return CreateMaybeMessage<Sphere>(NULL);
}
Sphere* New(::google::protobuf::Arena* arena) const final {
return CreateMaybeMessage<Sphere>(arena);
}
void CopyFrom(const ::google::protobuf::Message& from) final;
void MergeFrom(const ::google::protobuf::Message& from) final;
void CopyFrom(const Sphere& from);
void MergeFrom(const Sphere& from);
void Clear() final;
bool IsInitialized() const final;
size_t ByteSizeLong() const final;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const final;
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const final;
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Sphere* other);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return NULL;
}
inline void* MaybeArenaPtr() const {
return NULL;
}
public:
::google::protobuf::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
typedef Sphere_Position Position;
typedef Sphere_Scale Scale;
// accessors -------------------------------------------------------
// @@protoc_insertion_point(class_scope:Sphere.Sphere)
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
mutable ::google::protobuf::internal::CachedSize _cached_size_;
friend struct ::protobuf_sphere_2eproto::TableStruct;
};
// -------------------------------------------------------------------
class Spheres : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Sphere.Spheres) */ {
public:
Spheres();
virtual ~Spheres();
Spheres(const Spheres& from);
inline Spheres& operator=(const Spheres& from) {
CopyFrom(from);
return *this;
}
#if LANG_CXX11
Spheres(Spheres&& from) noexcept
: Spheres() {
*this = ::std::move(from);
}
inline Spheres& operator=(Spheres&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
#endif
static const ::google::protobuf::Descriptor* descriptor();
static const Spheres& default_instance();
static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
static inline const Spheres* internal_default_instance() {
return reinterpret_cast<const Spheres*>(
&_Spheres_default_instance_);
}
static constexpr int kIndexInFileMessages =
3;
void Swap(Spheres* other);
friend void swap(Spheres& a, Spheres& b) {
a.Swap(&b);
}
// implements Message ----------------------------------------------
inline Spheres* New() const final {
return CreateMaybeMessage<Spheres>(NULL);
}
Spheres* New(::google::protobuf::Arena* arena) const final {
return CreateMaybeMessage<Spheres>(arena);
}
void CopyFrom(const ::google::protobuf::Message& from) final;
void MergeFrom(const ::google::protobuf::Message& from) final;
void CopyFrom(const Spheres& from);
void MergeFrom(const Spheres& from);
void Clear() final;
bool IsInitialized() const final;
size_t ByteSizeLong() const final;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) final;
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const final;
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* target) const final;
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(Spheres* other);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return NULL;
}
inline void* MaybeArenaPtr() const {
return NULL;
}
public:
::google::protobuf::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
// repeated .Sphere.Sphere spheres = 1;
int spheres_size() const;
void clear_spheres();
static const int kSpheresFieldNumber = 1;
::Sphere::Sphere* mutable_spheres(int index);
::google::protobuf::RepeatedPtrField< ::Sphere::Sphere >*
mutable_spheres();
const ::Sphere::Sphere& spheres(int index) const;
::Sphere::Sphere* add_spheres();
const ::google::protobuf::RepeatedPtrField< ::Sphere::Sphere >&
spheres() const;
// @@protoc_insertion_point(class_scope:Sphere.Spheres)
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::RepeatedPtrField< ::Sphere::Sphere > spheres_;
mutable ::google::protobuf::internal::CachedSize _cached_size_;
friend struct ::protobuf_sphere_2eproto::TableStruct;
};
// ===================================================================

// ===================================================================
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// Sphere_Position
// float x = 1;
inline void Sphere_Position::clear_x() {
x_ = 0;
}
inline float Sphere_Position::x() const {
// @@protoc_insertion_point(field_get:Sphere.Sphere.Position.x)
return x_;
}
inline void Sphere_Position::set_x(float value) {

x_ = value;
// @@protoc_insertion_point(field_set:Sphere.Sphere.Position.x)
}
// float y = 2;
inline void Sphere_Position::clear_y() {
y_ = 0;
}
inline float Sphere_Position::y() const {
// @@protoc_insertion_point(field_get:Sphere.Sphere.Position.y)
return y_;
}
inline void Sphere_Position::set_y(float value) {

y_ = value;
// @@protoc_insertion_point(field_set:Sphere.Sphere.Position.y)
}
// float z = 3;
inline void Sphere_Position::clear_z() {
z_ = 0;
}
inline float Sphere_Position::z() const {
// @@protoc_insertion_point(field_get:Sphere.Sphere.Position.z)
return z_;
}
inline void Sphere_Position::set_z(float value) {

z_ = value;
// @@protoc_insertion_point(field_set:Sphere.Sphere.Position.z)
}
// -------------------------------------------------------------------
// Sphere_Scale
// float x = 1;
inline void Sphere_Scale::clear_x() {
x_ = 0;
}
inline float Sphere_Scale::x() const {
// @@protoc_insertion_point(field_get:Sphere.Sphere.Scale.x)
return x_;
}
inline void Sphere_Scale::set_x(float value) {

x_ = value;
// @@protoc_insertion_point(field_set:Sphere.Sphere.Scale.x)
}
// float y = 2;
inline void Sphere_Scale::clear_y() {
y_ = 0;
}
inline float Sphere_Scale::y() const {
// @@protoc_insertion_point(field_get:Sphere.Sphere.Scale.y)
return y_;
}
inline void Sphere_Scale::set_y(float value) {

y_ = value;
// @@protoc_insertion_point(field_set:Sphere.Sphere.Scale.y)
}
// float z = 3;
inline void Sphere_Scale::clear_z() {
z_ = 0;
}
inline float Sphere_Scale::z() const {
// @@protoc_insertion_point(field_get:Sphere.Sphere.Scale.z)
return z_;
}
inline void Sphere_Scale::set_z(float value) {

z_ = value;
// @@protoc_insertion_point(field_set:Sphere.Sphere.Scale.z)
}
// -------------------------------------------------------------------
// Sphere
// -------------------------------------------------------------------
// Spheres
// repeated .Sphere.Sphere spheres = 1;
inline int Spheres::spheres_size() const {
return spheres_.size();
}
inline void Spheres::clear_spheres() {
spheres_.Clear();
}
inline ::Sphere::Sphere* Spheres::mutable_spheres(int index) {
// @@protoc_insertion_point(field_mutable:Sphere.Spheres.spheres)
return spheres_.Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField< ::Sphere::Sphere >*
Spheres::mutable_spheres() {
// @@protoc_insertion_point(field_mutable_list:Sphere.Spheres.spheres)
return &spheres_;
}
inline const ::Sphere::Sphere& Spheres::spheres(int index) const {
// @@protoc_insertion_point(field_get:Sphere.Spheres.spheres)
return spheres_.Get(index);
}
inline ::Sphere::Sphere* Spheres::add_spheres() {
// @@protoc_insertion_point(field_add:Sphere.Spheres.spheres)
return spheres_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::Sphere::Sphere >&
Spheres::spheres() const {
// @@protoc_insertion_point(field_list:Sphere.Spheres.spheres)
return spheres_;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif  // __GNUC__
// -------------------------------------------------------------------
// -------------------------------------------------------------------
// -------------------------------------------------------------------

// @@protoc_insertion_point(namespace_scope)
}  // namespace Sphere
// @@protoc_insertion_point(global_scope)
#endif  // PROTOBUF_INCLUDED_sphere_2eproto

首先,除了声明嵌套类型之外,还需要在消息

中添加字段
message Sphere {

message Position {
float x = 1;
float y = 2;
float z = 3;
}
Position position = 1;
message Scale {
float x = 1;
float y = 2;
float z = 3;
}
Scale scale = 2;
}

那么我将重构如何创建和填充嵌套字段,使其类似于

auto sphere1 = sphereCollection.add_spheres();
sphere1->mutable_position()->set_x(5);
sphere1->mutable_position()->set_y(5);
sphere1->mutable_position()->set_z(5);
sphere1->mutable_scale()->set_x(5);
sphere1->mutable_scale()->set_y(5);
sphere1->mutable_scale()->set_z(5);
auto sphere2 = sphereCollection.add_spheres();
sphere2->mutable_position()->set_x(5);
sphere2->mutable_position()->set_y(5);
sphere2->mutable_position()->set_z(5);
sphere2->mutable_scale()->set_x(5);
sphere2->mutable_scale()->set_y(5);
sphere2->mutable_scale()->set_z(5);

,你可以使用add_*从当前对象分配一个嵌套的重复对象,并获得一个指针,类似地,mutable_*为所需的字段。

最新更新