2017-07-30 1 views
0

Salut, j'ai un exemple simple de addressbook.proto Je sérialisation en utilisant la fonction protobuf SerailizeToString() dans python. Voici le code.Conversion Python Protobuf en C++ en utilisant les fonctions Protobuf SerializeToString() et parseFromString()

import address_pb2 

person = address_pb2.Person() 
person.id = 1234 
person.name = "John Doe" 
person.email = "[email protected]" 
phone = person.phones.add() 
phone.number = "555-4321" 
phone.type = address_pb2.Person.HOME 

print(person.SerializeToString()) 

address_pb2 est le fichier que je généré à partir du compilateur protobuf. Notez que l'exemple est copié à partir des tutoriels protoBuf. Cela me donne la chaîne suivante.

b'\n\x08John Doe\x10\xd2\t\x1a\[email protected]"\x0c\n\x08555-4321\x10\x01' 

Maintenant, je veux importer cette chaîne dans C++ protobuf. Pour cela, j'ai écrit le code suivant.

#include <iostream> 
#include <fstream> 
#include <string> 
#include "address.pb.h" 
using namespace std; 

int main(int argc, char* argv[]) { 
    GOOGLE_PROTOBUF_VERIFY_VERSION; 


    tutorial::AddressBook address_book; 
    string data = "\n\x08""John Doe\x10""\xd2""\t\x1a""\x10""[email protected]\"\x0c""\n\x08""555-4321\x10""\x01"""; 
    if(address_book.ParseFromString(data)){ 
    cout<<"working"<< endl; 
    } 
    else{ 
    cout<<"not working" << endl; 
    } 


    // Optional: Delete all global objects allocated by libprotobuf. 
    google::protobuf::ShutdownProtobufLibrary(); 

    return 0; 
} 

Ici, je cherche simplement à importer le script en utilisant ParseFromString() fucntion mais cela ne fonctionne pas et je ne sais pas comment cela fonctionnera comme je l'ai été coincé sur ce depuis longtemps.

J'ai essayé de changer un peu le binaire en fonction de la version C++ mais je ne sais toujours pas si je suis sur la bonne voie ou non.

Comment puis-je y parvenir? Est-ce que quelqu'un a une idée?

Répondre

1

En Python, vous sérialisiez un objet Person. En C++, vous essayez d'analyser un objet AddressBook. Vous devez utiliser le même type aux deux extrémités.

(Notez que protobuf ne garantit pas qu'il détecte ces erreurs. Parfois, quand vous analysez un message comme le mauvais type, l'analyse syntaxique apparaît pour réussir, mais le contenu sera nettoyé.)


Il y a un autre problème avec votre code qui arrive de ne pas être un problème dans ce cas précis, mais ne fonctionnerait pas en général:

string data = "\n\x08""John Doe\x10""\xd2""\t\x1a""\x10""[email protected]\"\x0c""\n\x08""555-4321\x10""\x01"""; 

cette ligne ne fonctionnera pas si la chaîne a des octets NUL, à savoir ' \ x00 '. Si c'est le cas, cet octet serait interprété comme la fin de la chaîne. Pour éviter ce problème, vous devez spécifier la longueur des données, par exemple:

string data("\n\x08""John Doe\x10""\xd2""\t\x1a""\x10""[email protected]\"\x0c""\n\x08""555-4321\x10""\x01""", 45); 
+0

Le traitement avec l'objet 'Person' a permis de le faire fonctionner. le 45 que vous avez passé dans la chaîne de données, est-ce le str.len? – Mj1992

+0

Je viens d'avoir le même problème que vous avez mentionné dans la deuxième partie de votre réponse concernant '\ x00'. J'ai essayé de faire la même chose que vous dites en passant la longueur de la corde qui n'analyse pas la corde. Pourriez-vous s'il vous plaît m'aider. – Mj1992

+0

Oui, le 45 est la longueur de la chaîne en octets. Vous pouvez l'obtenir du côté de python en utilisant 'len()'. Notez que si vous essayez d'utiliser 'strlen()' du côté C++ pour obtenir la longueur, cela ne fonctionnera pas, car cela ne comptera que jusqu'au premier '\ x00'. –