2012-07-16 55 views
4

我刚才问了this question,并已解决为我的协议缓冲区中的enum值写入扩展。但是我有一个非常困难的时刻实际读取值回,即使这个简单的.proto文件:在协议缓冲区中读取enum扩展的值

package test; 

import "google/protobuf/descriptor.proto"; 

extend google.protobuf.EnumValueOptions { 
    optional string abbr = 54321; 
} 

message Person { 
    required string name = 1; 
    required int32 id = 2; 
    optional string email = 3; 
    enum PhoneType { MOBILE = 0 [(abbr)="Mobile ph"]; HOME = 1 [(abbr)="HomePhone"]; WORK = 2 [(abbr)="Work number"]; } 

    message PhoneNumber { 
     required string number = 1; 
     optional PhoneType type = 2 [default = HOME]; 
    } 

    repeated PhoneNumber phone = 4; 
} 

message AddressBook { 
    repeated Person person = 1; 
} 

我一直想这些和其他变体:

test::Person::PhoneNumber::descriptor()->options().GetExtension(test::abbr); 
test::Person::PhoneNumber::descriptor().GetExtension(test::abbr); 
test::Person::descriptor()->options().GetExtension(test::abbr); 

const google::protobuf::Descriptor* message = test::Person::PhoneNumber::descriptor(); 
const google::protobuf::Descriptor* desc = phone2.descriptor(); 
desc->options().GetExtension(test::abbr); //D.N.E. 

google::protobuf::MessageOptions opts = message->options(); 
opts.GetExtension(test::abbr); 

const google::protobuf::EnumDescriptor* enm = message->FindEnumTypeByName("PhoneNumber"); // null, not found 
google::protobuf::EnumValueOptions opts2 = enm->value(1)->options(); 
opts2.GetExtension(test::abbr); 

test::Person::PhoneNumber::descriptor()->options().GetExtension(test::abbr); 

以上无工作 - 该方法根本不存在,或者没有对该函数签名的匹配调用。我已经阅读了几个小时的文档无济于事。我知道这应该是可能的,但唯一的例子是编写.proto文件,而不是从它们读回 - 我该怎么做?一个简短的例子将非常感激。提前致谢。

回答

4

这有点复杂,但您需要获取手机类型的EnumValueDescriptor,然后在此调用options().GetExtension(test::abbr)

例如:

test::Person person; 
person.set_name("Caol Ila"); 
person.set_id(1); 

test::Person::PhoneNumber *phone = person.add_phone(); 
phone->set_number("01496 840207"); 
phone->set_type(test::Person::MOBILE); 

phone = person.add_phone(); 
phone->set_number("01496 840207"); 
phone->set_type(test::Person::HOME); 

phone = person.add_phone(); 
phone->set_number("01496 840207"); 
phone->set_type(test::Person::WORK); 

phone = person.add_phone(); 
phone->set_number("01496 840207"); 

const google::protobuf::EnumDescriptor* enum_desc = 
    test::Person::PhoneType_descriptor(); 
std::string value; 

for (int phone_index = 0; phone_index < person.phone_size(); ++phone_index) { 
    if (person.phone(phone_index).has_type()) { 
    int phone_type = person.phone(phone_index).type(); 
    value = enum_desc->value(phone_type)->options().GetExtension(test::abbr); 
    } 
} 
+0

完美地工作。非常感谢! – whrrgarbl 2012-07-17 13:39:15

+0

答案有一点误导:从EnumDescriptor获得EnumValueDescriptor需要枚举值索引,而不是枚举值本身。因此'phone_type'必须是'phone_type_enum_value_index'并且可以以另一种方式获得。当枚举值从零开始并且没有间隙地单调递增时,它并不重要,但是他们不能保证。 – 2016-02-12 08:56:04

+0

我发现''FindValueByNumber'替代'value',它通过枚举值返回EnumValueDescriptor而不是索引。最后一行是'value = enum_desc-> FindValueByNumber(phone_type) - > options()。GetExtension(test :: abbr);' – 2016-02-12 09:14:26