通过LevelDB将协议缓冲区序列化数据从C++传递到Python

Passing Protocol buffer serialized datas from C++ to Python via LevelDB

本文关键字:C++ Python 数据 LevelDB 协议 缓冲区 序列化 通过      更新时间:2023-10-16

尽管我学习了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"))

ad var类型为NoneType

编辑:在数据库之前。Get(),ab.ByteSize()在ParseFromString()之后返回0.76,我认为这是一个类型问题,那么。。。+ab.ListFields()返回包含字段的unexploitable列表:成功地定制了两个人实例,但无法让我访问它。

任何线索,任何我不理解的想法,我在这里做错了什么?

非常感谢!

好吧,这是我的错。

我回到了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

尝试使用'而不是":

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