【问题标题】:Protobuf c++ extensions useProtobuf c++ 扩展使用
【发布时间】:2016-08-15 20:59:32
【问题描述】:

我正在使用 google protobuf 库 2.61 版并想使用扩展,

我有以下 proto 文件:

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++ 中最优雅的方式是什么

【问题讨论】:

    标签: c++ protocol-buffers protobuf-c


    【解决方案1】:

    库解析消息和所有扩展。您可以使用 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;
    }
    

    【讨论】:

    • 好的,谢谢,所以唯一的选择是每次都迭代所有类型的扩展,直到我找到扩展?
    • 另外,您可以在基本消息中添加枚举字段'type',表示实际消息的类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 2010-11-07
    相关资源
    最近更新 更多