14

My .proto file looks like

message Cmd
{
      int code =  1;
}

message CmdOne
{
      required Cmd cmd = 1;
      required int data = 2;
}

message CmdTwo
{
      required Cmd cmd = 1;
      required string data = 2;
}

In my cpp file, I want to declare objects of CmdOne and CmdTwo and set both cmd and data members. But the generated pb.h file does not have a set method for the cmd member of CmdOne and CmdTwo objects, but has a set method for the data member. How do I set the value of cmd for each object?

I don't want to define message Cmd inside CmdOne and CmdTwo messages. I want to reuse the Cmd message as I have 10 messages CmdOne to CmdTen.

3 Answers 3

23

You have a couple of different options. You can get a non-const pointer to the cmd field, and then allocate value(s) appropriately:

CmdOne cmd_one;
Cmd* cmd(cmd_one.mutable_cmd());
cmd->set_code(2);
// Previous 2 lines could be simplified to:
// cmd_one.mutable_cmd()->set_code(2);

Alternativey, if you want to pass a constructed instance of Cmd into CmdOne, you can do:

Cmd* cmd(new Cmd);
cmd->set_code(1);

CmdOne cmd_one;
cmd_one.set_allocated_cmd(cmd);  // Takes ownership of cmd -
                                 // you don't call 'delete cmd'

From the "Singular Embedded Message Fields" section of the docs:

Given the message type:

message Bar {}

For either of these field definitions:

optional Bar foo = 1;
required Bar foo = 1;

The compiler will generate the following accessor methods:

...

Bar* mutable_foo()

Returns a mutable pointer to the Bar object that stores the field's value. If the field was not set prior to the call, then the returned Bar will have none of its fields set (i.e. it will be identical to a newly-allocated Bar). After calling this, has_foo() will return true and foo() will return a reference to the same instance of Bar. The pointer is invalidated by a call to Clear() or clear_foo().

...

void set_allocated_foo(Bar* bar)

Sets the Bar object to the field and frees the previous field value if it exists. If the Bar pointer is not NULL, the message takes ownership of the allocated Bar object and has_foo() will return true. Otherwise, if the Bar is NULL, the behavior is the same as calling clear_foo().

Sign up to request clarification or add additional context in comments.

1 Comment

How can I create a message file like in OP, from my C++ code. I have an input xml file which I parsed using C++ program and have data structures filled in. Is there a way to create a message file automatically from my c++ code? THanks
1
Cmd my_command;

theCommand.set_code(5);

CmdOne cmd_one;

cmd_one.mutable_cmd().copyFrom(my_command);

1 Comment

mutable_[something].copyFrom(other_something) actually copied given data. If you use set_allocated_[something]() for two parent objects, then when one parent dies, it destroys memory behind the child, then when other parent dies, it tries to destroy memory behind the same child, but itś already destroyed. This causes segmentation fault. So copyFrom() worked for me VERY WELL.
0

I think the simplest way is like this:

Cmd cmd;
cmd.set_code(1);
CmdOne cmd_one;
*(cmd_one.mutable_cmd()) = cmd;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.