2010-07-12 192 views
19

我想比较两个消息或(两个子参数)Google protocol buffers。 我没有找到一个API来实现它。谷歌协议缓冲区比较

任何想法?

+0

您可以指定您要比较的内容:消息结构,消息的字段值还是同时存在? – 2012-04-24 10:42:25

回答

-1

这可能不是理想的解决方案,但我认为它可以这样做:

messageA.DebugString() == messageB.DebugString(); 

除此之外,我认为唯一的解决办法是创建自己Message子类和实施bool operator==(const Message&)

+0

+1不错的尝试:)其实我需要它很快 – dimba 2010-07-12 18:31:45

+0

@idimba Tks。但是,我想你应该编辑你的问题,并提到速度的事情;-)。但是,我想,唯一真正的选择是自己实现比较操作符。 – Gianni 2010-07-12 18:41:42

+0

对于运营商而言+1,这是正确的方式。 – Yousf 2011-09-14 10:59:57

0

好吧,协议缓冲区只是某种对象类型的序列化格式。为什么不使用协议缓冲区来重建原始对象,然后允许这些对象比较自己,使用你在类中构建的任何比较逻辑?

8

而不是使用message.DebugString的你也可以做

std::string strMsg; 
message.SerializeToString(&strMsg); 

与两个消息,然后比较这两个(二进制)字符串。我没有测试性能,但我认为它比比较由.DebugString()返回的人类可读消息字符串更快。 +你可以用protobuf-lite库来做到这一点(而message.DebugString则需要完整版本)。

+1

序列化不能保证在二进制文件和一段时间内保持一致。例如,二进制未知的扩展将在已知扩展之后最后序列化(作为未知字段)。所以序列化将取决于序列化时可用的描述符。因此,比较序列化的消息是一个不好的检查是否相等。 MessageDifferencer是正确的方法。 – 2015-12-12 18:55:19

-3

您可以比较描述符的指针(超快速):

if (mMessages[i]->body()->GetDescriptor() == T::descriptor()) 

mMessages它与头和加密网络消息的游泳池,其创建与protobuf的身体包(谷歌:: protobuf的::消息* )。因此,为了获得正确的消息类型,我比较了描述符常量指针,它对于每种单一类型的消息都是相同的(不是%100确定,但我目前还没有任何问题)。

这将是最快的方法来比较一个protobuf消息wthout不得不使用字符串比较,通过这种方式你可以从描述符中获取类型名称。 :-)

+0

爱我的答案被拒绝了,但它是比较信息的正确方法。 – KukoBits 2013-09-25 23:49:15

+5

如果你想比较类型,这将是正确的,但这个问题似乎是关于比较内容,这当然是不行的。这就是为什么你得到了失望,我保证。 – 2013-10-22 18:42:50

17

您可以使用类google::protobuf::util::MessageDifferencer。我认为这是唯一可用的,因为v3.0.2

引入了新的效用函数/类在谷歌/的protobuf/UTIL 目录:

  • MessageDifferencer:比较两个原消息和报告他们之间的分歧。

MessageDifferencer::Equals(msg1, msg2);

+1

要添加:MessageDifferencer仅适用于C++ – deddebme 2015-09-15 19:22:56

+0

,具体取决于您的消息类型中的字段是否可以具有默认值,您可能需要考虑'MessageDifferencer :: Equivalent'而不是'Equals' – pestophagous 2017-08-15 22:40:45

4

你可以依靠的事实,所有的protobuf消息从google::protobuf::MesageLite类型,这反过来又需要比较任意两个protobuf的消息,一切都继承不管他们是即使是相同派生类型:

bool operator==(const google::protobuf::MessageLite& msg_a, 
       const google::protobuf::MessageLite& msg_b) { 
    return (msg_a.GetTypeName() == msg_b.GetTypeName()) && 
     (msg_a.SerializeAsString() == msg_b.SerializeAsString()); 
} 
+0

哇。这应该是这个用户问题的完美答案!好样的! – Peaches491 2016-08-11 23:43:54