doufu6423 2019-01-15 17:08
浏览 429

可以将protobuf元帅消息发送到已分配的字节数组而无需复制吗?

I am implementing client server communication by self defined packets. I am using Go net.conn. It can dial tcp/unix schemes which is very convenient. I use protocol buffer to define my messages.

I defined a Packet which contains length and buffer

type Packet struct {
    length uint32
    buffer []byte
}

The API function is like this:
func(api *API) Send(m *proto.Message) error
func(api *API) Receive(p *Packet) error

Take send function as an example, it takes in a protobuf message, marshal it into Packet. And write it to the net.conn.

Here is a simplified version of the Send function:

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
}

I was copying bytes into buffer. Because Go protocol buffer API only provides
func Marshal(pb Message) ([]byte, error)

In protocol buffer C++, it provides bool SerializeToArray(void * data, int size) const, which is serializing the message and storing it in the given byte array. But I can not find the same thing in Go protocol buffer API.

Is there any way to avoid the copy if I want to directly storing serialized result in the given byte array?

  • 写回答

3条回答

  • duanhongyi2964 2019-01-15 21:52
    关注

    It is not clear what you are asking. Notice that the proto Marshal() function does exactly what you are looking for: It serializes the message into a byte slice (what you probably mean by byte array)

    See if either of these help:

    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
    }
    

    Or

    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
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?