2017-02-15 2 views
1

Je me demandais juste, pourquoi quelqu'un n'a pas encore rencontré le problème que j'ai récemment en rapport avec google protobufs, mais après googling étendu, lire la documentation de la page de manuel de google et la recherche dans Stackoverflow-DB, je n'ai pas trouvé de solution. J'utilise proto2-C++-API sur un LTS Ubuntu 14.04.3, en compilant avec gcc/g ++ sur cmake-files.Modification d'un élément d'un message protobuf existant en C++

J'ai une application qui lit des messages de tampon de protocole google binaires (sérialisés) à partir d'un fichier. Le but du programme est alors d'envoyer les messages (sans désérialisation) à une autre application, qui procède au traitement des données réelles.

Je voudrais maintenant modifier certains des messages, lus à partir du fichier, afin que je puisse tester la fonctionnalité de la deuxième application. Malheureusement, mon message comprend un grand nombre de messages imbriqués, donc après désérialisation je dois appeler quelque chose comme

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

pour être en mesure de travailler avec les données réelles.

Ma question est maintenant, comment je peux changer la valeur de x sans créer un autre message de type message où je dois aussi créer tous les sous-messages (a,b,c...) et d'affecter ces derniers avec le prédécesseur respectif comme dans le pseudo- suivant code?!

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; 

De toute évidence, il est impossible d'appeler set_value directement sur les message -Objets respectivement ses sous-objets comme message().a().b().c()....x().set_value();, comme on contreviendrait aux dispositions const des messages protobuf générés automatiquement, où il est autorisé à appeler une méthode setter sur un objet const: error: passing xxx as 'this' argument of xxx discards qualifiers

J'apprécierais toute solution créative pour éviter d'implémenter le code récursif new-set_allocated-delete, posté ci-dessus.

Merci à l'avance

Répondre

3

La clé est d'utiliser les mutable_x() accesseurs, donc dans votre exemple, vous feriez quelque chose comme ceci:

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

Les set_allocated_* méthodes sont en fait pas vraiment recommandée, à moins que vous Vous savez vraiment ce que vous faites, car ils vous donnent un contrôle particulier sur la gestion de la mémoire dont vous n'avez normalement pas besoin, sauf si vous essayez spécifiquement d'optimiser un morceau de code particulier.

0

Merci pour votre réponse, Adam Cozzette. L'utilisation des accesssors mutable_x est la solution à mon problème.

Néanmoins, j'ai quelques autres questions sur les méthodes de classe fournies du produit protobuf C++ - Code:

Quand il est recommandé de ne pas utiliser les méthodes set_allocated_x - comment puis-je mettre réellement la valeur d'un message imbriqué? Dans l'exemple ci-dessus, je voudrais par exemple aime changer mutable_c, qui est un protobuf-message lui-même. Je ne vois pas d'autre méthode que les `set_allocated'ones à utiliser dans ce scénario ?!

Ma deuxième question serait, quand utiliser les méthodes getter standard et quand les mutable_x()?Est-ce simplement une différence de lecture/écriture, ce qui signifie que j'utiliserais le premier pour obtenir les valeurs actuelles et le second pour les changer?

+0

Si vous voulez simplement affecter une nouvelle valeur à certains sous-message 'C' alors vous pouvez juste faire une affectation régulière avec = comme ceci:' * b.mutable_c() = other_c; ' –

+0

Et vous avez raison au sujet de la les getters standard contre les mutables; c'est juste une différence de lecture/écriture. –

+0

C'est tout. Merci pour votre effort. – Weana