0

I am a novice trying to use google protobuf for work project. I want to find out difference between protobuf messages and hence trying to use the MessageDifferencer APIs. I get the SEGV while running the code below. Commenting the line "reporter->ReportModified(*Obj1, *Obj2, field_path);" results in no segv Any help in usage of differencer appreciated!

google::protobuf::util::MessageDifferencer diff;
diff.set_report_matches(false);
diff.set_report_moves(false);
std::string reportDiff;
google::protobuf::io::StringOutputStream* opstream = new google::protobuf::io::StringOutputStream(&reportDiff);
google::protobuf::util::MessageDifferencer::StreamReporter* reporter =  new google::protobuf::util::MessageDifferencer::StreamReporter(opstream);
diff.ReportDifferencesTo(reporter);

std::vector<google::protobuf::util::MessageDifferencer::SpecificField> field_path;
try
{
    reporter->ReportModified(*Obj1, *Obj2, field_path);
}
catch (const std::exception& e)
{
    std::cout << e.what() <<"\n";
}

cout << __func__ << " Report added " << field_path.size();

//Cleanup objects
delete Obj1; 
delete Obj2;
delete reporter;

Thanks, Maddy

maddypj
  • 1
  • 1
  • I'm afraid the question as is doesn't have enough to go on. Ideally you would provide a Minimal, Reproducible Example - something that allows reproducing the problem (https://stackoverflow.com/help/minimal-reproducible-example). For example, one of the most important aspects here would be where `Obj1` and `Obj2` come from. A stack trace of the crash would also be extremely useful if you can get it. – Rafael Lerm Aug 06 '20 at 20:04
  • Thanks! Will keep that in mind next time! – maddypj Aug 07 '20 at 23:52

1 Answers1

0

You shouldn't be calling the ReportModified method directly, the MessageDifferencer class calls it when it finds a difference.

MessageDifferencer::Compare is the correct method to call, according to the docs. Assuming all else is correct, I believe changing your code inside the try-loop to call that should work.

Moving your code to a function, you could have something like

std::string CompareMessages(
    const google::protobuf::Message& m1,
    const google::protobuf::Message& m2) {
  using google::protobuf::util::MessageDifferencer;

  MessageDifferencer diff;
  diff.set_report_matches(false);
  diff.set_report_moves(false);
  std::string reportDiff;
  {
    google::protobuf::io::StringOutputStream opstream(&reportDiff);
    MessageDifferencer::StreamReporter reporter(&opstream);
    diff.ReportDifferencesTo(&reporter);

    diff.Compare(m1, m2);
  }
  return std::move(reportDiff);
}
Rafael Lerm
  • 1,340
  • 7
  • 10
  • Thank you for the response! The compare works. I believe we can implement our own reporter class and call the ReportModified in that implementation. My intention was to use the specific field paths. – maddypj Aug 07 '20 at 23:55
  • replace `diff.ReportDifferencesToString(&reportDiff);` with `diff.ReportDifferencesTo(&reporter);` is more convenient. – Alexander Chen Aug 05 '21 at 09:50