【问题标题】:Passing Protocol buffer serialized datas from C++ to Python via LevelDB通过 LevelDB 将协议缓冲区序列化数据从 C++ 传递到 Python
【发布时间】:2012-01-28 13:33:08
【问题描述】:

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

我可以使用 C++ 中的协议缓冲区(使用 std::string 容器)序列化我的数据。我可以将它插入LevelDB。但是,当我 levelDB->获取我的序列化数据时,虽然 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"))

ad var 类型为 NoneType

编辑: 在 db.Get() 之前,ab.ByteSize() 在 ParseFromString() 之后返回 0、76,我认为这是一个类型问题... + ab.ListFields() 返回包含字段的unexploitable 列表:成功计算两个人实例,但无法让我访问它。

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

非常感谢!

【问题讨论】:

  • 您可以尝试再次在 c++ 中反序列化对象以确保序列化工作正常。
  • 是的,我已经尝试在 C++ 中反序列化它,并且效果很好:-)

标签: c++ serialization protocol-buffers key-value leveldb


【解决方案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

【讨论】:

    【解决方案2】:

    尝试使用' 而不是"

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

    【讨论】:

    • 虽然 Python 中的单引号和双引号是等价的,但我试过了,还是不行 :-) 结果还是 NoneType。
    猜你喜欢
    • 1970-01-01
    • 2016-11-10
    • 1970-01-01
    • 2011-08-26
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多