GPB SerializeTo函数问题

时间:2013-11-18 05:31:17

标签: c++ rabbitmq protocol-buffers

我有以下代码。

main()
{
    test::RouteMessage *Rtmesg = new test::RouteMessage;
    test::RouteV4Prefix *prefix = new test::RouteV4Prefix;
    test::RouteMessage testRtmesg;

    prefix->set_family(test::RouteV4Prefix::RT_AFI_V4);
    prefix->set_prefix_len(24);
    prefix->set_prefix(1000);

    Rtmesg->set_routetype(test::RouteMessage::RT_TYPE_BGP);
    Rtmesg->set_allocated_v4prefix(prefix);
    Rtmesg->set_flags(test::RouteMessage::RT_FLGS_NONE);
    Rtmesg->set_routeevnt(test::RouteMessage::BGP_EVNT_V4_RT_ADD);
    Rtmesg->set_nexthop(100);
    Rtmesg->set_ifindex(200); Rtmesg->set_metric(99);
    Rtmesg->set_pref(1);
    int size = Rtmesg->ByteSize();

    char const *rt_msg = (char *)malloc(size);

    google::protobuf::io::ArrayOutputStream oarr(rt_msg, size);
    google::protobuf::io::CodedOutputStream output (&oarr)

    Rtmesg->SerializeToCodedStream(&output);


    // Below code is just to see if everything is fine.
    google::protobuf::io::ArrayInputtStream iarr(rt_msg, size);
    google::protobuf::io::CodedInputStream Input (&iarr)

    testRtmesg.ParseFromCodedStream(&Input);

    Vpe::RouteV4Prefix test_v4Prefix = testRtmesg.v4prefix();
    cout << std::endl;
    std::cout << "Family " << test_v4Prefix.family() << std::endl;
    std::cout << "Prefix " << test_v4Prefix.prefix()<< std::endl;
    std::cout << "PrefixLen " << test_v4Prefix.prefix_len() << std::endl;

    // All the above outputs are fine.

    cout << std::endl;
    cout << rt_msg; <<------------ This prints absolutely junk.
    cout << std::endl;

    amqp_bytes_t str2; 
    str2 = amqp_cstring_bytes(rt_msg);  <<----- This just crashes.
    printf("\n str2=%s %d", str2.bytes, str2.len);

}

对上述rt_msg的任何操作都会崩溃。我想使用上面的缓冲区发送到socket和另一个rabbitmq发布API。

那里有类似问题的人还是制定了相似的代码?

1 个答案:

答案 0 :(得分:0)

协议缓冲区是二进制序列化格式,而不是文本。这意味着:

  • 是的,如果您将二进制数据写入cout,它将看起来像垃圾(或崩溃)。
  • 数据不像C字符串那样以NUL方式终止。因此,你不能将它传递给像amqp_cstring_bytes那样需要NUL终止char*的函数 - 它可能会在前0字节处缩短数据,或者它可能会搜索超过0的字节。缓冲区结束和崩溃。通常,任何采用char*但不占用长度的函数都不起作用。

我不熟悉amqp,但看起来你试图调用的函数amqp_cstring_bytes只是构建一个amqp_bytes_t,其定义如下:

typedef struct amqp_bytes_t_ {
  size_t len;
  void *bytes;
} amqp_bytes_t;

所以,你所要做的就是:

amqp_bytes_t str2;
str2.bytes = rt_msg;
str2.len = size;