在 protobuf C++ 中处理枚举值 0
Handling enum value 0 in protobuf c++
我正在开发一个使用 protobuf 进行数据序列化的 C++17 项目,但我遇到了一个问题。
我试图将protobuf中定义的一个对象序列化为std::string并且该对象只有一个枚举字段,当不小心将该字段的值设置为0时,函数SerializeAsString()或SerializToString(std::string* ) 将 return true 但我总是得到一个空字符串。
我查看了 google api 参考资料,但没有任何帮助,有人可以帮助我吗?我写了一些代码来说明这个问题。
假设我们要在testProtobuf.proto
中定义一种消息
syntax = "proto3";
package pb;
message testPackage{
enum testEnums{
TEST_0=0;
TEST_1=1;
TEST_2=2;
}
testEnums enumValue=1;
}
我使用
编译它
protoc --cpp_out=./ testProtobuf.proto
在 testProtobuf.cpp 中我们有:
#include<iostream>
#include<string>
#include "testProtobuf.pb.h"
int main(){
pb::testPackage t0,t1,t2;
t0.set_enumvalue(pb::testPackage::TEST_0);
t1.set_enumvalue(pb::testPackage::TEST_1);
t2.set_enumvalue(pb::testPackage::TEST_2);
std::cout<<t0.ShortDebugString()<<"\n"<<t1.ShortDebugString()<<"\n"<<t2.ShortDebugString()<<std::endl;
std::string temp;
std::cout<<"Success? "<<t0.SerializeToString(&temp)<<", Length: "<<temp.length()<<std::endl;
std::cout<<"Success? "<<t1.SerializeToString(&temp)<<", Length: "<<temp.length()<<std::endl;
std::cout<<"Success? "<<t2.SerializeToString(&temp)<<", Length: "<<temp.length()<<std::endl;
return 0;
}
然后我们编译文件:
g++ testProtobuf.cpp testProtobuf.pb.cc -lprotobuf -lpthread -o test.exe
当运行可执行文件时,它打印出这些第一行留空:
enumValue: TEST_1
enumValue: TEST_2
Success? 1, Length: 0
Success? 1, Length: 2
Success? 1, Length: 2
我怀疑这与“\0”有关,但我没有更好的办法让它发挥作用。
甚至 SerializeToArray() returns true 并且保持我传入的缓冲区不变。我只需要获取对象的序列化形式。谁能帮我?非常感谢!!
protoc版本为3.6.1,g++版本为9.3.0,主机系统为Ubuntu20.04.3
这实际上根本不是问题,因为解析将按预期工作,因为这是 protobuf
处理方式的一部分 default values:
Also note that if a scalar message field is set to its default, the value will not be serialized on the wire.
因此,因为 protobuf
不区分设置为其默认值的字段和根本未设置的字段,它根本不序列化默认值,并且在这种情况下您的字符串为空。
此外,这不仅适用于 enums
,还适用于所有标量类型:
message testPackage2 {
int32 intValue=1;
}
pb::testPackage2 in, out;
out.set_intvalue(0);
std::cout << "Success? " <<out.SerializeToString(&temp)<< ", Length: " << temp.length() << std::endl;
in.ParseFromString(temp);
std::cout<<"Parsed: " << in.intvalue() << std::endl;
也会产生一个空的序列化字符串,但仍能正确解析:
Success? 1, Length: 0
Parsed: 0
我正在开发一个使用 protobuf 进行数据序列化的 C++17 项目,但我遇到了一个问题。
我试图将protobuf中定义的一个对象序列化为std::string并且该对象只有一个枚举字段,当不小心将该字段的值设置为0时,函数SerializeAsString()或SerializToString(std::string* ) 将 return true 但我总是得到一个空字符串。
我查看了 google api 参考资料,但没有任何帮助,有人可以帮助我吗?我写了一些代码来说明这个问题。
假设我们要在testProtobuf.proto
中定义一种消息syntax = "proto3";
package pb;
message testPackage{
enum testEnums{
TEST_0=0;
TEST_1=1;
TEST_2=2;
}
testEnums enumValue=1;
}
我使用
编译它 protoc --cpp_out=./ testProtobuf.proto
在 testProtobuf.cpp 中我们有:
#include<iostream>
#include<string>
#include "testProtobuf.pb.h"
int main(){
pb::testPackage t0,t1,t2;
t0.set_enumvalue(pb::testPackage::TEST_0);
t1.set_enumvalue(pb::testPackage::TEST_1);
t2.set_enumvalue(pb::testPackage::TEST_2);
std::cout<<t0.ShortDebugString()<<"\n"<<t1.ShortDebugString()<<"\n"<<t2.ShortDebugString()<<std::endl;
std::string temp;
std::cout<<"Success? "<<t0.SerializeToString(&temp)<<", Length: "<<temp.length()<<std::endl;
std::cout<<"Success? "<<t1.SerializeToString(&temp)<<", Length: "<<temp.length()<<std::endl;
std::cout<<"Success? "<<t2.SerializeToString(&temp)<<", Length: "<<temp.length()<<std::endl;
return 0;
}
然后我们编译文件:
g++ testProtobuf.cpp testProtobuf.pb.cc -lprotobuf -lpthread -o test.exe
当运行可执行文件时,它打印出这些第一行留空:
enumValue: TEST_1
enumValue: TEST_2
Success? 1, Length: 0
Success? 1, Length: 2
Success? 1, Length: 2
我怀疑这与“\0”有关,但我没有更好的办法让它发挥作用。 甚至 SerializeToArray() returns true 并且保持我传入的缓冲区不变。我只需要获取对象的序列化形式。谁能帮我?非常感谢!!
protoc版本为3.6.1,g++版本为9.3.0,主机系统为Ubuntu20.04.3
这实际上根本不是问题,因为解析将按预期工作,因为这是 protobuf
处理方式的一部分 default values:
Also note that if a scalar message field is set to its default, the value will not be serialized on the wire.
因此,因为 protobuf
不区分设置为其默认值的字段和根本未设置的字段,它根本不序列化默认值,并且在这种情况下您的字符串为空。
此外,这不仅适用于 enums
,还适用于所有标量类型:
message testPackage2 {
int32 intValue=1;
}
pb::testPackage2 in, out;
out.set_intvalue(0);
std::cout << "Success? " <<out.SerializeToString(&temp)<< ", Length: " << temp.length() << std::endl;
in.ParseFromString(temp);
std::cout<<"Parsed: " << in.intvalue() << std::endl;
也会产生一个空的序列化字符串,但仍能正确解析:
Success? 1, Length: 0
Parsed: 0