我被困在一個簡單但令人心痛的任務中:在C 中進行資料決議。我需要將一個Protobuf物件的資料內容序列化為std::vector<uint8_t>。我已經看到了幾個例子,使用SerializeToArray方法將資料序列化到*void或char[]緩沖區,但并不適合我的需要。我希望能有個幫手,謝謝你的支持。
注意:我需要的是SerializeToArray方法。
注意:我需要std::vector<uint8_t>,而不是std::vector<uint8_t>&或者其他。
uj5u.com熱心網友回復:
直接的解決方案是預設std::vector<uint8_t>到正確的大小:
size_t nbytes = std::vector<uint8_t> v(proto_object. ByteSizeLong()) 。
/* 該測驗是必要的,因為如果nbytes為0,v.data可能為NULL */。
if (nbytes)
proto_object.SerializeToArray(v.data(), nbytes) 。
這里唯一的問題是,v的內容在被SerializeToArray覆寫之前被建構式設定為0。這不是一個錯誤;代碼可以正常作業。但這是一種低效率。
能夠創建未初始化的值的向量是一個長期的討論點。有一些方法可以做到這一點,但是簡單的方法需要使用與std::vector<uint8_t>有細微差別的型別:一種可能性是使用帶有自定義分配器的向量;另一種是使用基于uint8_t的非初始化資料型別。這兩種方法都很煩人,因為你不能在不復制向量的情況下改變它的分配器或值型別,這就違背了目的。
因此,最簡單的事情就是接受低效率,這可能并不嚴重,因為將序列化的資料發送到它要去的地方的成本可能會使不必要的啟動相形見絀。無論如何,清除記憶體肯定比從臨時緩沖區中復制更便宜,而且它不需要創建臨時緩沖區。
uj5u.com熱心網友回復:
如果你需要使用一個std::vector,你可以這樣做(從我的頭開始):
#include <vector>
#include <cstdint>/span>
//調整此值以符合你的最大資訊量。
constexpr MAX_N_BYTES = 100。
//在向量中為你的資訊分配足夠的空間。
std::vector<uint8_t> vec;
vec.reserve(MAX_N_BYTES)。
//>你的資訊的分配。
YourMessage msg;
///設定一些資料
msg.set_x(1234)。
//接下來將資料序列化為向量。
msg.SerializeToArray(vec.data(), vec.max_size() 。)
但是我不建議你像這樣使用std::vector。矢量容器實際上是被設計用來在頂層管理下面的記憶體。
在我看來,一個更合適的容器是std::array。這是一個更接近于正常C風格陣列的容器。對于它的實作將看起來像:
#include <array>
#include <cstdint>
//調整這個值以符合你的最大資訊量。
constexpr MAX_N_BYTES = 100。
//分配陣列
std::array<uint8_t, MAX_N_BYTES> array。
//你的訊息的分配。
YourMessage msg;
// 設定一些資料 // 設定一些資料。
msg.set_x(1234)。
//接下來將資料序列化為陣列。
msg.SerializeToArray(array.data(), MAX_N_BYTES) 。
注意在這兩種情況下,你真的需要提前知道你的資訊的最大尺寸。這樣才能分配到合適的記憶體量。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/329427.html
標籤:
