2016-08-15 9 views
0

Я использую Google Protobuf версии библиотеки 2.61 и хочу использовать расширение,Protobuf C++ расширения используют

У меня есть следующие проты файлы:

package communication; 

message BaseMessage { 
    required uint64 server_id  = 1; 
    required string uuid   = 2; 
    required uint64 message_id = 3; 

    extensions 100 to max; 
} 

message GetIdentify { 

    extend BaseMessage { 
    optional GetIdentify message = 100; 
    } 

    required string hostname = 1; 
} 

Я могу построить сообщение, используя следующее код:

communication::BaseMessage base_message; 
base_message.set_message_id(123456); 
base_message.set_server_id(112313123); 
base_message.set_uuid("asdaskdjasd213123123asd"); 
base_message.MutableExtension(communication::GetIdentify::message)->set_hostname("http://test123123123ing"); 

Однако я хотел бы сделать противоположное действие и получить сообщение с неизвестным расширением и разобрать его и найти какое расширение это и анализировать в соответствии с ним.

Я использовал nanopb для моего проекта c и версии python. но мне очень сложно написать protobuf-код в C++, потому что я не могу найти достаточно документации и примеров кода.

Есть ли способ сделать это без добавления дополнительной переменной типа расширения?

Кроме того, что это самый элегантный способ сделать это в C++

ответ

0

разбора сообщений библиотеки и всех расширений. Вы можете проверить наличие расширения с использованием метода HasExtension.

Реализация Java должна регистрировать расширения в синтаксическом анализаторе перед разбором. Но на C++ все делается автоматически. См. Следующий код. (Я тестировал с Protobuf 2.5.0)

Создание и написать сообщение:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <communication/p.pb.h> 
using namespace std; 

int 
main(int, char **) 
{ 
    communication::BaseMessage base_message; 
    base_message.set_message_id(123456); 
    base_message.set_server_id(112313123); 
    base_message.set_uuid("asdaskdjasd213123123asd"); 
    base_message.MutableExtension(communication::GetIdentify::message)->set_hostname("http://test123123123ing"); 
    base_message.SerializeToOstream(&cout); 
    return 0; 
} 

Чтение сообщений, расширение тестирования и распечатать его:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <communication/p.pb.h> 
#include <google/protobuf/text_format.h> 
using namespace google::protobuf; 
using namespace std; 

int 
main(int, char **) 
{ 
    communication::BaseMessage base_message; 
    base_message.ParseFromIstream(&cin); 

    if (base_message.HasExtension(communication::GetIdentify::message)) { 
     const communication::GetIdentify &ii = base_message.GetExtension(communication::GetIdentify::message); 
     cout << "yes, msg has extension: " << ii.hostname() << endl << endl; 
    } else { 
     cout << "no, msg has no extension" << endl << endl; 
    } 

    string res; 
    TextFormat::PrintToString(base_message, &res); 

    cout << res << endl; 
    return 0; 
} 
+0

Ok спасибо, поэтому, единственный вариант итерации каждый раз, когда все типы расширений существуют, пока я не найду расширение? – RythemOfTheDay

+0

Кроме того, вы можете добавить перечислимое поле 'type' в базовое сообщение, указав тип фактического сообщения. –