protobuf 的 repeated 字段在遇到 0 的时候,就很奇怪啊 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
amiwrong123
V2EX    程序员

protobuf 的 repeated 字段在遇到 0 的时候,就很奇怪啊

  •  1  
  •   amiwrong123 2020-03-07 16:15:38 +08:00 4343 次点击
    这是一个创建于 2074 天前的主题,其中的信息可能已经有所发展或是发生改变。
    message mess { optional int32 No = 1; repeated int32 IDs = 2; } 

    然后我是从 java 层传到 c++层,这个 IDs 字段里,只有没有加入 0 这个数,c++层收到后都是正常的,但只要加入了 0,c++层解析出来的就不对了。

    比如: IDs 字段为 [ 64,65,33,22,0 ] ,C++层再解析出来,就只有 [ 64,65,33,22 ] 了.

    IDs 字段为 [ 64,65,33,22,0,22 ] ,C++层再解析出来,就变成 [ 64,65,33,22,64 ] 了

    总之,只要有 0 在里面,就会很奇怪。

    java 层是这么做的,通过 HIDl 接口发给 c++层。

    mess proto = new mess(); proto.No = 1; proto.IDs = new int[] {64,65,33,22,0}; String sendString = new String(mess.toByteArray(proto)); 

    c++层是这么解析的:

    std::string strProtoBuf = Obj->getProtoInfo(); //反正这里得到了,传来的字符串 mess proto; mess.ParseFromString(strProtoBuf); 

    求助各位大佬,该怎么解啊

    19 条回复    2020-03-09 10:41:11 +08:00
    lixia625
        1
    lixia625  
       2020-03-07 17:17:04 +08:00
    0 是 int32 的默认值,protobuf 对于默认值就不传了(为了效率)
    sikong31
        2
    sikong31  
       2020-03-07 19:28:17 +08:00
    JAVA 和 C++都打个断点,看看编码后的字节一样不一样
    不一样在考虑考虑 protobuf 版本的问题
    wanglufei
        3
    wanglufei  
       2020-03-07 20:30:23 +08:00 via Android
    看下 protobuf 的数据格式 跟下源码
    Sasasu
        4
    Sasasu  
       2020-03-07 20:42:03 +08:00
    最简单的办法是给 repeated packed=true 看看
    会改变序列化方式 java 和 c++ 都需要重新编译
    controller
        5
    controller  
       2020-03-07 22:33:08 +08:00 via Android
    golang protobuf 生成的代码默认加上了 omotempty 的 tag,要么你改下他的源码,要么传字符串
    controller
        6
    controller  
       2020-03-07 22:33:29 +08:00 via Android
    omit
    turi
        7
    turi  
       2020-03-07 22:39:36 +08:00
    自己看字节流吧,反正 protobuf int 字段解析很简单,看看到底是哪个地方接错了
    amiwrong123
        8
    amiwrong123  
    OP
       2020-03-07 23:52:03 +08:00   1
    @lixia625
    @sikong31
    @wanglufei
    @Sasasu
    @controller
    @turi

    真相大白了,是我不该用 string 作为载体的。
    比如我在 java 层执行了 mess.toByteArray(proto),如果 IDs 字段为 [ 64,65,33,22,0 ] 转换成的字节数组为 [8 1 16 64 16 3 16 65 16 7 16 67 16 36 16 0 ] ,再执行 new String()就丢掉最后面那个 0.

    然后我加接口了,让接口 直接传递那个字节数组就好了。

    哎,怪自己考虑不周。
    coer
        9
    coer  
       2020-03-08 01:07:08 +08:00 via Android
    有的字节不是在 unicode 上找不到对应字符,然后被替换成 0xfffd,随便什么字节转字符不会出错吗,还是我记错了...
    terryching
        10
    terryching  
       2020-03-08 08:07:02 +08:00 via Android
    你们跨平台传都不序列化的吗
    laminux29
        11
    laminux29  
       2020-03-08 08:58:50 +08:00
    @amiwrong123

    这不是你考虑不周的问题,这明明就是 api 的问题。包装一下就把数据给丢了,这问题太严重了。
    livepps
        12
    livepps  
       2020-03-08 09:26:09 +08:00 via Android
    二进制转字符串的都会我也遇到过,跟你的不大一样,是浮点数有问题,后来就不转了 string 了,用二进制 api 收发数据
    sikong31
        13
    sikong31  
       2020-03-08 10:09:36 +08:00 via iPhone
    @laminux29 这和 protobuf 的 api 没有关系,是 java string 的 api 的对 byte 数组行为的。错的是不应该转成 string
    laminux29
        14
    laminux29  
       2020-03-08 10:38:28 +08:00
    @sikong31

    1.Java 的 byte 数组转 String 的 API,处理上没问题。

    2.byte 数组转 string,这是个很常见的需求,没有不应该一说。
    coer
        15
    coer  
       2020-03-08 17:01:18 +08:00 via Android
    @laminux29 随便什么 bytes 数组转 string 保存要指定字符集是 iso-8895-1,默认的如果是 unicode 是不行的吧
    laminux29
        16
    laminux29  
       2020-03-08 17:09:16 +08:00
    @coer 试试总比猜测好,对不?
    coer
        17
    coer  
       2020-03-08 17:23:20 +08:00 via Android
    我是说 new string(byte[]).getBytes()出来的字节数组和原字节数组可能是不一样的
    amiwrong123
        18
    amiwrong123  
    OP
       2020-03-08 22:06:42 +08:00
    @coer
    你说的这个,我试了一下,在 java 的话,两个字节数组是一样的。

    但是呢,好像是一旦传到了 C++层后,接受到字符串就不对。而我在 C++层解析后,会丢掉字节数组最后的 0,好像是因为 c++的字符串最后是以'\0'结尾的,所以会丢掉最后的 0。
    coer
        19
    coer  
       2020-03-09 10:41:11 +08:00
    @amiwrong123 你用 random 生成 bytes 多试几次吧,如果是默认的 uncoded 字符集,不说内容了,长度都可能不一样
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5263 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 07:09 PVG 15:09 LAX 23:09 JFK 02:09
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86