protobuf 使用中发现的一个问题

来源:互联网 发布:电脑安装软件需要密码 编辑:程序博客网 时间:2024/03/28 16:24


首先先说一下版本

protoc  --version

2.5.0


然后说一下bug是什么,就是在把一个对象序列化成一个ostringstream后,如果再把另一个对象序列化到同一个ostringstream后,会发现第二个对象变成了两个对象。

即使ostringstream.clear() 后一样会有问题


先上协议文件, 标准的example

package lm; 
message helloworld
{
    required int32     id = 1;  // ID
    required string    str = 2;  // str
    optional int32     opt = 3;  //optional field


    repeated int32      value = 4;
}


然后再上测试代码,

#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string.h>


#include "helloworld.pb.h"


using namespace std;
using namespace lm; 
using namespace google::protobuf;


int main()
{


    helloworld hello;


    hello.set_id( 100 );
    hello.set_str( "this is a test ");
    hello.set_opt( 200 );
    for( int i=0; i<100; ++i)
    {   
        hello.add_value( i );    
    }   


    ostringstream ss; 
    hello.SerializeToOstream( &ss );


    string data = ss.str();


    cout << data.length() << endl;;
    cout << data << endl;


   ss.flush();           //even flush is not work
    ss.clear();        // attention:we have clear the stream

    
    helloworld hello2;


    hello2.set_id( 100 );
    hello2.set_str( "this is a test ");
    hello2.set_opt( 200 );
    for( int i=0; i<100; ++i)
    {   
        hello2.add_value( i );    
    }   
    hello2.SerializeToOstream( &ss );
    string data2 = ss.str();


    cout << data2 <<endl;
    cout << data2.length() << endl;




    return 0;
}



结果是

222
dthis is a test �           
 
  
                     ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c
dthis is a test �           
 
  
                     ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b dthis is a test �          
 
  
                     ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c
444


显然,两个同样的hello对象连在一起了.


我一开始觉得这应该是protobuf的一个bug, 因为按照正常的stream使用标准,在我们clear,flush后,不应该在流中保留已有的东西。


为了验证我的想法,我马上又写了一个小test, 来排除是stringstream的问题。


代码如下,

#include <sstream>
#include <iostream>
#include <string>


using namespace std;


int main()
{
    ostringstream ss; 
    ss.str("haha");
    string data = ss.str();
    cout << data.length() << endl;
    ss.clear();
    data = ss.str();
    cout << data.length() << endl;
    return 0;
}


我以为输出应该是4,0,但是很意外结果是4,4

这说明了,不是protobuf的问题,而是stringstream的问题,在clear,flush之后,并没有清空流。


最后上google搜了一下,为什么stringstream.clear 不起作用。

发现有大把人跟我遇到过一样的问题啊

在clear之前,加一句 ss.str( string() );

即设置一个空的string,通过这种方式来清空流。即,需要同时清空流,以及流中的string


做到这里先告一段落,后续我需要看看stringstream的原码,看看为什么不置空string就达不到清空流的目的!



原创粉丝点击