Ruby中Google::Protobuf::Any解包时lookup返回nil如何解决?
问题原因
- Ruby版本的Protobuf库默认不会将官方定义的Well-Known Types(如
google.protobuf.Int64Value这类标准类型)预注册到Google::Protobuf::DescriptorPool.generated_pool中,你没有提前加载对应类型定义时,lookup操作就会返回nil,触发后续的空指针报错。 - 你手动构造
Google::Protobuf::Any实例的方式不符合规范:Any的value字段要求传入目标消息序列化后的二进制字节流,你直接传入明文字符串'1',就算descriptor查询成功,后续解包也会触发解析错误。
修复方案
首先需要提前导入你用到的标准类型定义,加载后类型会自动注册到全局DescriptorPool中:
require 'google/protobuf/wrappers_pb'
常规使用方式(推荐)
优先使用Any.pack方法打包目标对象,不要手动填充type_url和value字段,避免出错:
# 构造目标类型实例 int64_obj = Google::Protobuf::Int64Value.new(value: 1) # 自动打包为Any实例,自动填充正确的type_url和序列化后的value any_value = Google::Protobuf::Any.pack(int64_obj) # 此时lookup可以正常获取descriptor type = Google::Protobuf::DescriptorPool.generated_pool.lookup(any_value.type_name) value = any_value.unpack(type) # 输出解包后的数值:1 puts value.value
必须手动构造Any的特殊场景
如果业务要求必须手动指定type_url和value,需要确保value是目标消息序列化后的二进制数据:
require 'google/protobuf/wrappers_pb' # 先将目标对象序列化为二进制 serialized = Google::Protobuf::Int64Value.new(value: 1).to_proto any_value = Google::Protobuf::Any.new( type_url: 'type.googleapis.com/google.protobuf.Int64Value', value: serialized ) type = Google::Protobuf::DescriptorPool.generated_pool.lookup(any_value.type_name) value = any_value.unpack(type)
内容的提问来源于stack exchange,提问作者septerr
相关产品推荐
相关产品推荐

