Передача сериализованных данных из буфера протокола из C ++ в Python через LevelDB - PullRequest
0 голосов
/ 28 января 2012

Несмотря на то, что я следовал великолепной документации и учебным пособиям по протоколу буфера для C ++ и Python, я не могу достичь своей цели: сериализовать данные из процесса C ++. - вставьте его в LevelDB из того же процесса. - извлечь сериализованные данные из процесса Python - Десерализовать это из того же самого процесса Python - Используйте эти десерализованные данные в Python

Я могу сериализовать свои данные, используя буфер протокола в C ++ (используя контейнер std :: string). Я могу вставить его в LevelDB. Но когда я выровняю DB-> получить мои сериализованные данные, хотя Python, кажется, распознает их как строку и показывает мне их необработанный контент, всякий раз, когда я десериализую его в строку Python, он пуст!

Вот как я сериализую и вставляю свои данные в C ++:

int                             main(int arg, char** argv)
 {
     GOOGLE_PROTOBUF_VERIFY_VERSION;

     leveldb::DB*                  db;
     leveldb::Options              options;
     leveldb::Status               status;
     tutorial::AddressBook         address_book;
     tutorial::Person*             person1;
     tutorial::Person*             person2;

     options.create_if_missing = true;
     status = leveldb::DB::Open(options, "test_db", &db);
     assert(status.ok());

     person1 = address_book.add_person();
     person1->set_id(1);
     person1->set_name("ME");
     person1->set_email("me@me.com");

     person2 = address_book.add_person();
     person2->set_id(2);
     person2->set_name("SHE");
     person2->set_email("she@she.com");

     std::string                   test;
     if (!address_book.SerializeToString(&test))
     {
         std::cerr << "Failed to write address book" << std::endl;
         return -1;
     }

     if (status.ok()) status = db->Put(leveldb::WriteOptions(), "Test", test);

А вот как я пытаюсь десериализовать его в Python:

address_book = addressbook_pb2.AddressBook()
db = leveldb.LevelDB('test_db')
ab = address_book.ParseFromString(db.Get("Test"))

тип объявления - NoneType

Редактировать: до того, как db.Get (), ab.ByteSize () вернет 0, 76 после ParseFromString (), я предполагаю, что это проблема типа ... + ab.ListFields () возвращает список unexploitable содержащегося поля: успешно отслеживает два экземпляра человека, но не может дать мне доступ к нему.

Любые подсказки, любые идеи о том, что я не понял, что я здесь делаю не так?

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 29 января 2012

Хорошо, так это было плохо.

Я вернулся к документации Python для буферов протокола, и дело в том, что даже если объект AdressBook, который я извлекал, не показывал никакого описания, он все еще мог быть повторен и даже имел. str ().

так что, если кто-то снова столкнется с этой проблемой, просто попробуйте исследовать ваш объект ProtocolBuffers, используя iPython, как я, и вы обнаружите, что каждый из ваших протологических элементовполя вашего объекта.Используя мой пример:

ab = adress_book.ParseFromString(db.Get('Test'))
ab.__str__()  # Shows a readable version of my object
for person in adress_book.person:  # I'm even able to iterate over any of my ab fields values
    print person.id
    print person.name
0 голосов
/ 28 января 2012

Попробуйте использовать ' вместо ":

ab = address_book.ParseFromString(db->Get('Test'))
...