2016-08-15 64 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'到基本消息,指示实际消息的类型。 –