如何从 C++ 中的 protobuf 获取信息?
How to get information from your protobuf in C++?
基本上我要做的是从类似于 SHPObject
类型的 ProtoBuf 消息中获取 x
和 y
坐标。我知道使用 SHPObject
我可以做 double* x = obj->padfX
和 double* y = obj->padfY
之类的事情。但是,我不完全确定如何从我的 ProtoBuf 中提取相同的信息(代码如下所示)。感谢您的帮助!
到目前为止我已经尝试过:
myProject::protobuf::NewShape _NewShape;
auto obj = _NewShape.shape(0);
double* x = obj.polygon(0).point(0);
报错:
cannot initialize a variable of the type 'double' with an rvalue of type 'unsigned int'
然后我尝试了这个编译但没有做任何事情(没有给我想要的输出):
double x_coordinate = obj.polygon(0).point(0);
double *x_ptr = &x_coordinate;
这是我的 ProtoBuf 文件:
newShape.proto
syntax = "proto2";
package myProject.protobuf;
message NewShape {
message Polygon
{
enum PolygonType {
POLY_TYPE_OUTER = 1;
POLY_TYPE_INNER = 2;
};
optional PolygonType type = 1 [default = POLY_TYPE_OUTER];
// x, y coordinates
repeated uint32 point = 2 [packed = true];
}
message Shape
{
repeated Polygon polygon = 1;
}
repeated Shape shape = 2;
}
根据您的格式,您可以像这样从正确填充和反序列化的对象访问点:
// newShape is the deserialized object here
const auto s0p0p0 = newShape.shape(0).polygon(0).point(0);
const auto s0p0p1 = newShape.shape(0).polygon(0).point(1);
类似地,shape(1)
会给你第二个形状来访问它在多边形对象中的点。您应该在访问索引之前检查 *_size()
方法以确保有效访问,例如newShape.shape_size()
、shape.polygon_size()
和 polygon.point_size()
。
如果您打算修改消息,可以使用 mutable_*
方法获取指向相应对象的指针,然后您可以更改它们。
例如(第一个形状的第一个多边形的变化点):
auto p = newShape2.mutable_shape(0);
p->mutable_polygon(0)->set_point(0, 123);
p->mutable_polygon(0)->set_point(1, 345);
这是序列化和反序列化的完整工作示例:
#include <iostream>
#include "newShape.pb.h"
int main()
{
// Serailization
::myProject::protobuf::NewShape newShape1;
auto shape1 = newShape1.add_shape();
auto polygon1 = shape1->add_polygon();
polygon1->add_point(1);
polygon1->add_point(2);
auto shape2 = newShape1.add_shape();
auto polygon2 = shape2->add_polygon();
polygon2->add_point(3);
polygon2->add_point(4);
const auto serializedData = newShape1.SerializeAsString();
std::cout << "Serialized Data Size: " << serializedData.size() << "\n\n";
// Send/Store Serialized Data
// Deserialization
::myProject::protobuf::NewShape newShape2;
if ( !newShape2.ParseFromString( serializedData ) )
{
std::cerr << "Deserialization failed!\n";
return -1;
}
std::cout << "Deserialized Data Size: " << newShape2.ByteSize() << "\n\n";
std::cout << "NewShape [Shapes: " << newShape2.shape_size() << "]\n";
for ( int i {0}; i < newShape2.shape_size(); ++i )
{
std::cout << " Shape # " << i << '\n';
const auto& shape = newShape2.shape( i );
for ( int j {0}; j < shape.polygon_size(); ++j )
{
std::cout << " Polygon # " << j << '\n';
const auto& polygon = shape.polygon( j );
for ( int k {0}; k < polygon.point_size(); ++k )
{
const auto& point = polygon.point( k );
std::cout << " Point # " << k << ": " << point << '\n';
}
}
}
return 0;
}
输出:
Serialized Data Size: 16
Deserialized Data Size: 16
NewShape [Shapes: 2]
Shape # 0
Polygon # 0
Point # 0: 1
Point # 1: 2
Shape # 1
Polygon # 0
Point # 0: 3
Point # 1: 4
基本上我要做的是从类似于 SHPObject
类型的 ProtoBuf 消息中获取 x
和 y
坐标。我知道使用 SHPObject
我可以做 double* x = obj->padfX
和 double* y = obj->padfY
之类的事情。但是,我不完全确定如何从我的 ProtoBuf 中提取相同的信息(代码如下所示)。感谢您的帮助!
到目前为止我已经尝试过:
myProject::protobuf::NewShape _NewShape;
auto obj = _NewShape.shape(0);
double* x = obj.polygon(0).point(0);
报错:
cannot initialize a variable of the type 'double' with an rvalue of type 'unsigned int'
然后我尝试了这个编译但没有做任何事情(没有给我想要的输出):
double x_coordinate = obj.polygon(0).point(0);
double *x_ptr = &x_coordinate;
这是我的 ProtoBuf 文件:
newShape.proto
syntax = "proto2";
package myProject.protobuf;
message NewShape {
message Polygon
{
enum PolygonType {
POLY_TYPE_OUTER = 1;
POLY_TYPE_INNER = 2;
};
optional PolygonType type = 1 [default = POLY_TYPE_OUTER];
// x, y coordinates
repeated uint32 point = 2 [packed = true];
}
message Shape
{
repeated Polygon polygon = 1;
}
repeated Shape shape = 2;
}
根据您的格式,您可以像这样从正确填充和反序列化的对象访问点:
// newShape is the deserialized object here
const auto s0p0p0 = newShape.shape(0).polygon(0).point(0);
const auto s0p0p1 = newShape.shape(0).polygon(0).point(1);
类似地,shape(1)
会给你第二个形状来访问它在多边形对象中的点。您应该在访问索引之前检查 *_size()
方法以确保有效访问,例如newShape.shape_size()
、shape.polygon_size()
和 polygon.point_size()
。
如果您打算修改消息,可以使用 mutable_*
方法获取指向相应对象的指针,然后您可以更改它们。
例如(第一个形状的第一个多边形的变化点):
auto p = newShape2.mutable_shape(0);
p->mutable_polygon(0)->set_point(0, 123);
p->mutable_polygon(0)->set_point(1, 345);
这是序列化和反序列化的完整工作示例:
#include <iostream>
#include "newShape.pb.h"
int main()
{
// Serailization
::myProject::protobuf::NewShape newShape1;
auto shape1 = newShape1.add_shape();
auto polygon1 = shape1->add_polygon();
polygon1->add_point(1);
polygon1->add_point(2);
auto shape2 = newShape1.add_shape();
auto polygon2 = shape2->add_polygon();
polygon2->add_point(3);
polygon2->add_point(4);
const auto serializedData = newShape1.SerializeAsString();
std::cout << "Serialized Data Size: " << serializedData.size() << "\n\n";
// Send/Store Serialized Data
// Deserialization
::myProject::protobuf::NewShape newShape2;
if ( !newShape2.ParseFromString( serializedData ) )
{
std::cerr << "Deserialization failed!\n";
return -1;
}
std::cout << "Deserialized Data Size: " << newShape2.ByteSize() << "\n\n";
std::cout << "NewShape [Shapes: " << newShape2.shape_size() << "]\n";
for ( int i {0}; i < newShape2.shape_size(); ++i )
{
std::cout << " Shape # " << i << '\n';
const auto& shape = newShape2.shape( i );
for ( int j {0}; j < shape.polygon_size(); ++j )
{
std::cout << " Polygon # " << j << '\n';
const auto& polygon = shape.polygon( j );
for ( int k {0}; k < polygon.point_size(); ++k )
{
const auto& point = polygon.point( k );
std::cout << " Point # " << k << ": " << point << '\n';
}
}
}
return 0;
}
输出:
Serialized Data Size: 16
Deserialized Data Size: 16
NewShape [Shapes: 2]
Shape # 0
Polygon # 0
Point # 0: 1
Point # 1: 2
Shape # 1
Polygon # 0
Point # 0: 3
Point # 1: 4