2017-02-15 10 views
1

Мне просто интересно, почему никто не сталкивался с проблемой, которую я недавно имел в связи с google protobufs, но после обширного поиска в Google, чтения документации на странице руководства Google и поиска в Stackoverflow-DB я не нашел решения.Изменение элемента существующего сообщения protobuf в C++

Я использую proto2-C++ - API на Ubuntu 14.04.3 LTS, компилируя с gcc/g ++ поверх cmake-файлов.

У меня есть приложение, которое считывает двоичные (сериализованные) сообщения буфера протокола Google из файла. Затем целью программы является отправка сообщений (без десериализации) в другое приложение, которое обрабатывает фактические данные.

Теперь я хочу изменить некоторые сообщения, прочитанные из файла, чтобы я мог проверить функциональность второго приложения. К сожалению, мое сообщение включает в себя множество вложенных сообщений, так что после десериализации я должен назвать что-то вроде

message().a().b().c()....x().value(); 

, чтобы иметь возможность работать с фактическими данными.

Мой вопрос теперь, как я могу изменить значение x без создания другого сообщения типа message где я должен создать все суб-сообщения (a,b,c...) и распределить их с соответствующим предшественником, как в следующем псевдо- код?!

a = new a(); 
b = new b(); 
c = new c(); 
... 
v = new v(); 
w = new w(); 
x = new x(); 
x.set_value(); 
w.set_allocated_x_value(x); 
v.set_allocated_w_value(w); 
... 
a.set_allocated_b_value(b); 
message.set_allocated_a_value(a); 

... 
/* forward message to second application */ 
... 


delete x; 
delete w; 
... 
delete a; 

Очевидно, что это не представляется возможным назвать set_value непосредственно на message -Объекты, соответственно его подобъектов как message().a().b().c()....x().set_value();, как можно было бы нарушить константные требования автоматически сгенерированных Protobuf-сообщений о, где не разрешено вызывать метод setter на const-объекте: error: passing xxx as 'this' argument of xxx discards qualifiers

Я был бы признателен любым креативным решениям, чтобы избежать реализации рекурсивного кода new-set_allocated-delete, опубликованного выше.

Заранее спасибо

ответ

3

Ключом к этому является использование mutable_x() аксессоров, так что в вашем примере вы могли бы сделать что-то вроде этого:

message.mutable_a()->mutable_b()->mutable_c()->set_value(42); 

В set_allocated_* методы фактически не на самом деле не рекомендуется, если вам действительно знаю, что вы делаете, потому что они дают вам особый контроль над управлением памятью, который вам обычно не нужен, если вы специально не пытаетесь оптимизировать определенный фрагмент кода.

0

Спасибо за ваш отзыв, Адам Коззетт. Использование mutable_x - это решение моей проблемы.

Тем не менее у меня есть некоторые дополнительные вопросы о предоставляемых методах классов сгенерированной Protobuf C++ - код:

Когда не рекомендуется использовать set_allocated_x методы - как я могу на самом деле установить значение вложенного сообщения? В приведенном выше примере я бы, например, как изменить mutable_c, что является сообщением protobuf. Я не вижу другого метода, кроме `set_allocated'ones для использования в этом сценарии ?!

Моим вторым вопросом было бы, когда использовать стандартные геттер-методы и когда у вас есть mutable_x()?Разве это просто отличие чтения/записи, то есть я бы использовал первый, чтобы получить текущие значения, а второй - изменить их?

+0

Если вы хотите просто присвоить новое значение некоторому подчиненному 'c', вы можете просто выполнить регулярное присвоение с = следующим образом:' * b.mutable_c() = other_c; ' –

+0

И вы правы в отношении стандартные геттеры против изменчивых; это просто разница чтения/записи. –

+0

Вот и все. Спасибо за ваши усилия. – Weana