亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

可以將 protobuf 編組消息發送到已分配的字節數組而無需復制嗎?

可以將 protobuf 編組消息發送到已分配的字節數組而無需復制嗎?

Go
慕妹3146593 2023-06-01 15:17:39
我正在通過自定義數據包實現客戶端服務器通信。我正在使用圍棋net.conn??梢該芴杢cp/unix schemes,非常方便。我用來protocol buffer定義我的消息。我定義了一個包含length和buffertype Packet struct {    length uint32    buffer []byte}API函數是這樣的:func(api *API) Send(m *proto.Message) errorfunc(api *API) Receive(p *Packet) error以send函數為例,它接收一個 protobuf 消息,將其編組為Packet. 并將其寫入net.conn.下面是 Send 函數的簡化版本:func(api *API) Send(m *proto.Message) error {    bytes, err := proto.Marshal(m)    if err != nil {        return err    }    buffer := api.packet[:length]    copy(buffer, bytes)    _, err := api.conn.Write(buffer)    if err != nil {        return err    }    return nil}我正在復制bytes到buffer. 因為 Go protocol buffer API 只提供func Marshal(pb Message) ([]byte, error)在 Protocol Buffer C++ 中,它提供了 bool SerializeToArray(void * data, int size) const,它正在序列化消息并將其存儲在給定的字節數組中。但是我在 Go protocol buffer API 中找不到同樣的東西。如果我想直接將序列化結果存儲在給定的字節數組中,有什么辦法可以避免復制?
查看完整描述

3 回答

?
慕田峪9158850

TA貢獻1794條經驗 獲得超7個贊

您正在尋找來自 的MarshalTo方法gogo/protobuf,它是 protobuf 的另一種實現,與原始方法兼容。

當您將要填充的緩沖區傳遞給它時,您可以通過多個編組調用重新使用同一個緩沖區。顯然緩沖區應該足夠大。

func?MarshalTo([]byte,?m)?error


查看完整回答
反對 回復 2023-06-01
?
慕碼人2483693

TA貢獻1860條經驗 獲得超9個贊

似乎你可以Packet.buffer成為一個proto.Buffer

type Packet struct {

? ? length uint32

? ? buffer proto.Buffer

}

...

var packet Packet

packet.length = YouLength

packet.buffer = proto.NewBuffer(make([]byte, YouLength))

//Then you can Marshall in Packet directly and it? may be reused.

err := packet.Marshal(message)


查看完整回答
反對 回復 2023-06-01
?
RISEBY

TA貢獻1856條經驗 獲得超5個贊

目前尚不清楚你在問什么。請注意,原型 Marshal() 函數完全符合您的要求:它將消息序列化為字節切片(您可能指的是字節數組)


看看這些是否有幫助:


func(api *API) Send(m *proto.Message) error {

    p := Packet{}

    p.buffer, err := proto.Marshal(m)

    if err != nil {

        return err

    }

    _, err := api.conn.Write(p.buffer)

    if err != nil {

        return err

    }

    return nil

}

或者


func(api *API) Send(m *proto.Message) error {

    buffer := api.packet[:length]

    buffer, err := proto.Marshal(m)

    if err != nil {

        return err

    }

    _, err := api.conn.Write(buffer)

    if err != nil {

        return err

    }

    return nil

}


查看完整回答
反對 回復 2023-06-01
  • 3 回答
  • 0 關注
  • 169 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號