0

尽管我遵循了 C++ 和 Python 的优秀协议缓冲区文档和教程,但我无法实现我的目标: - 从 C++ 进程中序列化数据。- 从同一进程将其插入 LevelDB。- 从 Python 进程中提取序列化数据 - 从同一个 Python 进程中反序列化 - 在 Python 中使用那些反序列化的数据

我可以使用 C++ 中的协议缓冲区(使用 std::string 容器)序列化我的数据。我可以将它插入LevelDB。但是,当我 levelDB->Get 我的序列化数据时,虽然 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() 在 ParseFromString() 之后返回 0、76,我认为这是一个类型问题然后... + ab.ListFields() 返回unexploitable包含字段的列表:成功计算两个人实例,但无法让我访问它。

任何线索,关于我不明白的任何想法,我在这里做错了什么?

非常感谢!

4

2 回答 2

1

好吧,这是我的错。

我回到了 Protocol Buffers Python 文档,事实是即使我正在检索的 AdressBook 对象没有显示任何描述,它仍然能够被迭代,甚至有一个 . str () 方法。

所以,如果有人再次遇到这个问题,只需像我一样尝试使用 iPython 探索您的 ProtocolBuffers 对象,您会发现您的每个 proto 元素都是您的对象的字段。使用我的例子:

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
于 2012-01-29T09:13:38.537 回答
0

尝试使用'而不是"

ab = address_book.ParseFromString(db->Get('Test'))
于 2012-01-28T13:49:44.470 回答