V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  程序员

protobuf 在通过 hidl 接口传输时,是不是应该用 string 啊

  •  
  •   amiwrong123 · 2019-08-13 17:24:02 +08:00 · 1799 次点击
    这是一个创建于 1938 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 Android 的 java 层往 native 层的一个 service 传输一个 protobuf 的字符串: 首先 proto 文件( information )很简单:

    syntax = "proto2";
    option optimize_for = LITE_RUNTIME;
    message info {
        optional int32  member = 1;
    }
    

    mk 里面分别编译了 java 库和 c++库:

    include $(CLEAR_VARS)
    LOCAL_SRC_FILES := \
        $(call all-proto-files-under, proto) \
    
    LOCAL_MODULE := xxx
    
    LOCAL_MODULE_TAGS := optional
    
    LOCAL_VENDOR_MODULE := true
    
    #LOCAL_PROTOC_OPTIMIZE_TYPE := nano
    
    LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/
    
    LOCAL_SHARED_LIBRARIES := liblog
    
    include $(BUILD_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_SRC_FILES := \
        $(call all-proto-files-under, proto) \
    
    LOCAL_MODULE := xxx.aaa.bbb
    
    LOCAL_MODULE_TAGS := optional
    
    LOCAL_VENDOR_MODULE := true
    
    #LOCAL_PROTOC_OPTIMIZE_TYPE := nano
    
    LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/
    
    include $(BUILD_STATIC_JAVA_LIBRARY)
    

    在 java 层时这么塞数据的:

    information.info data = information.info();
    data.member = 150;
    String buf = new String(information.info.toByteArray(data));
    //然后通过 hidl 接口传过去
    

    在 c++层这么解数据的:

    info data;
    data.ParseFromString(buf);
    

    现在问题是,当我在 info 的 member 赋值 127 以上的数字时,就会出错,c++层解析出来变成 2 万多,127 或以下的值就没有问题。是我在塞数据的时候用错了吗?

    (还有一点 proto 文件自动生成的 java 文件是继承的 messagenano,而生成的 c++代码继承的是 messagelite,这两个好像不一样啊)

    7 条回复    2019-08-14 17:12:06 +08:00
    amiwrong123
        1
    amiwrong123  
    OP
       2019-08-13 19:35:23 +08:00 via Android
    自己顶一下,话说我这帖子是不是应该发在安卓区…
    amiwrong123
        2
    amiwrong123  
    OP
       2019-08-13 19:55:34 +08:00
    mk 文件里面,这个 LOCAL_PROTOC_OPTIMIZE_TYPE := nano 是没有注释掉的,忘改了。
    Monad
        3
    Monad  
       2019-08-13 20:55:39 +08:00 via iPhone
    lz 在 cxx 层十六进制输出一下 buf 看看呢 只有一个字段的话 人肉很好解析的
    amiwrong123
        4
    amiwrong123  
    OP
       2019-08-14 14:10:33 +08:00
    @Monad
    谢谢,现在感觉应该是 String buf = new String(information.info.toByteArray(data));有问题,因为这句对字符串编码时用的是 UTF-8,这是一个字符对应两个字节的,而我应该用"ISO-8859-1"编码方法,这是一个字符对应一个字节的。
    Monad
        5
    Monad  
       2019-08-14 14:15:53 +08:00
    @amiwrong123 #4 Protobuf 的 string 是要求必须为 UTF-8 编码的 如果非 UTF-8 编码应该用 bytes 哈. 虽然内部表示是一样的 但是解析的库可能会报错.
    建议还是在 C++层 Hexdump 一下 贴上来好分析.
    amiwrong123
        6
    amiwrong123  
    OP
       2019-08-14 14:31:10 +08:00
    @Monad
    “ Protobuf 的 string 是要求必须为 UTF-8 编码”,是这样的吗,我在官网上好像没看到这句话。

    反正现在比较尴尬,

    java 的序列化相关方法是(用字节数组):
    byte[] toByteArray();: serializes the message and returns a byte array containing its raw bytes.
    static Person parseFrom(byte[] data);: parses a message from the given byte array.

    c++的序列化相关方法是(用 string ):
    bool SerializeToString(string* output) const;: serializes the message and stores the bytes in the given string. Note that the bytes are binary, not text; we only use the string class as a convenient container.
    bool ParseFromString(const string& data);: parses a message from the given string.

    所以我感觉是字节数组转字符串的时候出了问题,等会我打印出来看看。。
    Monad
        7
    Monad  
       2019-08-14 17:12:06 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1453 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 17:21 · PVG 01:21 · LAX 09:21 · JFK 12:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.