我正在開發一個使用 protobuf 進行資料序列化的 C 17 專案,但遇到了一個問題。
我試圖將 protobuf 中定義的物件序列化為 std::string 并且該物件只有一個列舉欄位,當該欄位的值意外設定為 0 時,函式 SerializeAsString() 或 SerializToString(std::string*) 將回傳 true 但我總是得到一個空字串。我檢查了谷歌 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() 也回傳 true 并保持我傳入的緩沖區不變。我需要的只是獲取物件的序列化形式。誰能幫我?萬分感謝!!
protoc版本為3.6.1,g 版本為9.3.0,宿主系統為Ubuntu 20.04.3
uj5u.com熱心網友回復:
這實際上根本不是問題,因為決議將按預期作業,因為這是protobuf處理默認值的一部分:
另請注意,如果標量訊息欄位設定為其默認值,則該值將不會在線上序列化。
因此,因為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
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/430116.html
標籤:C 协议缓冲区 protobuf-c
上一篇:是否需要定義所有前向宣告?
