0

I am trying to use the protobuf-c library to send messages in between sockets in C.

Steps to reproduce

  1. Create a .proto file with the messages:
syntax = "proto3";

message MyMsg {}
  1. Compile it with protoc c_out=. rpc.proto I get my rpc.pb-c.h/c files ready to use.

  2. Include the header, try to pack an empty message.

int main () {
    MyMsg msg = MY_MSG__INIT;
    size_t buflen = my_msg__get_packed_size(&msg);
    printf("buflen: %zu\n", buflen);
}

prints 0.

Further details

Even if I ignore this and I allocate a larger buffer for packing the msg, the my_msg__pack(buf), function will not write any bytes into the buffer.

If I define a non-empty message, I do get some bytes into the buffer. Still, it seems to me the generated code only packs the body of the message, not the header, indicating the type of the message.

Question

Is there some other API I need to use in order to pack the whole message?

doplumi
  • 2,938
  • 4
  • 29
  • 45

1 Answers1

1

Since your message is defined as an empty one, e.g. no fields, the length of the serialized message is, of course, 0. This is true, even if you define a message with some fields, but NOT set any field of the message.

message MyMsg {
  int32 i = 1;  // if you don't call MyMsg::set_i(int), the length of the serialized message is still 0.
}

not the header, indicating the type of the message.

Protobuf does NOT encode meta data, e.g. message type, into the serialized value. Instead, the protobuf definition file is the meta data. That's why you must have a protobuf file, if you want to parse the serialized data.

Also if you have 2 messages with exactly the same definition, you can even parse the serialized data of one message to build another message.

message A {
}

message B {
  // have the same fields definition with A
}

A a;
serialized_data = serialize(a);

B b;
parse(b, serialized_data);
for_stack
  • 21,012
  • 4
  • 35
  • 48