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 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)