How to distinguish between messages?

812 views
Skip to first unread message

pbaranov

unread,
Feb 19, 2017, 8:26:17 PM2/19/17
to Protocol Buffers
It's probably something trivial but I can't figure it out :( I have 2 messages that have similar structure and when I try to encode message #1 and decode it as message #2 it works just fine. Why??? If that's how it is supposed to work how to distinguish between them? Please advise. Self contained fest code is below. Another probably very close related question: if message in .proto file is empty (does not contain any fields) it is serialised into zero byte long data. Is this how it is supposed to be? Than how to send such a message?

.proto

syntax = "proto2";

package test;

message Msg1
{
required int32 x = 1;
}

message Msg2
{
required int32 y = 1;
}

test.cpp

#include <string>
#include <iostream>

#ifdef _DEBUG
#pragma comment(lib,"./protobuf-3.2.0/lib/libprotobufd.lib")
#pragma comment(lib,"./protobuf-3.2.0/lib/libprotocd.lib")
#else
#pragma comment(lib,"./protobuf-3.2.0/lib/libprotobuf.lib")
#pragma comment(lib,"./protobuf-3.2.0/lib/libprotoc.lib")
#endif

#include ".pb.h"

int main(int argc, char* argv[])
{
std::string str;
test::Msg1 msg1; msg1.set_x(1);
if (!msg1.SerializeToString(&str))
{
std::cerr << "failed to serialise packet" << std::endl;
return -1;
}
test::Msg2 msg2;
if (!msg2.ParseFromString(str))
{
std::cerr << "failed to parse packet" << std::endl;
return -1;
}
std::cerr << "UNEXPECTED: type Msg1 was successfully parsed as type Msg2, why ???" << std::endl;
return 0;
}

Brian Palmer

unread,
Feb 21, 2017, 4:46:07 AM2/21/17
to pbaranov, Protocol Buffers
On Sun, Feb 19, 2017 at 5:26 PM pbaranov <bender...@gmail.com> wrote:
It's probably something trivial but I can't figure it out :( I have 2 messages that have similar structure and when I try to encode message #1 and decode it as message #2 it works just fine. Why??? If that's how it is supposed to work how to distinguish between them? Please advise.

You're not missing anything; the standard wire format for protocol buffers does not include the names of anything, only the fields and types.  Your communication protocol will need some higher level coordination to handle what types of message should be sent.

One possible way of encoding this sort of information into a protocol buffer is to use a container message, such as 

message OuterMessage {
  oneof messages {
     Msg1 msg1 = 1;
     Msg2 msg2 = 2;  
   }
}

Where each possible message is specified in the oneof group. Then in your C++ code handling the received outer message, you can switch on the result of messages_case() to know which inner message was actually sent. 


Reply all
Reply to author
Forward
0 new messages