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

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

  •  
  •   amiwrong123 · 10 天前 · 591 次点击

    在 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
        1
    amiwrong123   9 天前 via Android
    自己顶一下,话说我这帖子是不是应该发在安卓区…
        2
    amiwrong123   9 天前
    mk 文件里面,这个 LOCAL_PROTOC_OPTIMIZE_TYPE := nano 是没有注释掉的,忘改了。
        3
    Monad   9 天前 via iPhone
    lz 在 cxx 层十六进制输出一下 buf 看看呢 只有一个字段的话 人肉很好解析的
        4
    amiwrong123   9 天前
    @Monad
    谢谢,现在感觉应该是 String buf = new String(information.info.toByteArray(data));有问题,因为这句对字符串编码时用的是 UTF-8,这是一个字符对应两个字节的,而我应该用"ISO-8859-1"编码方法,这是一个字符对应一个字节的。
        5
    Monad   9 天前
    @amiwrong123 #4 Protobuf 的 string 是要求必须为 UTF-8 编码的 如果非 UTF-8 编码应该用 bytes 哈. 虽然内部表示是一样的 但是解析的库可能会报错.
    建议还是在 C++层 Hexdump 一下 贴上来好分析.
        6
    amiwrong123   9 天前
    @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.

    所以我感觉是字节数组转字符串的时候出了问题,等会我打印出来看看。。
        7
    Monad   9 天前
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3419 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 20ms · UTC 10:06 · PVG 18:06 · LAX 03:06 · JFK 06:06
    ♥ Do have faith in what you're doing.