2016-08-15 58 views
0

我使用谷歌的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"); 

不過,我想這樣做相反的動作,並與認識的擴展得到消息並解析它,發現它是一個擴展,並根據其解析。

我已經爲我的c項目和python版本使用nanopb。但我發現在C++中編寫protobuf代碼非常困難,因爲我找不到足夠好的文檔和代碼示例。

有沒有辦法做到這一點,而無需添加額外的擴展類型的變量?

還什麼是最優雅的方式在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

好的,謝謝你,所以通過唯一的選擇是每次都遍歷所有類型的擴展存在,直到找到擴展名爲止? – RythemOfTheDay

+0

此外,你可以添加枚舉字段'type'到基本消息,指示實際消息的類型。 –