c++ - 通过 LevelDB 将 Protocol Buffer 序列化数据从 C++ 传递到 Python

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

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

我可以使用 C++ 中的 Protocol Buffer (使用 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() 返回 0,在 ParseFromString() 之后返回 76,我认为这是一个类型问题...... + ab.ListFields() 返回包含字段的 unexploitable 列表:成功计算出两个 person 实例,但无法让我访问它。

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

非常感谢!

最佳答案

好吧,这是我的错。

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

关于c++ - 通过 LevelDB 将 Protocol Buffer 序列化数据从 C++ 传递到 Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9045629/

相关文章:

c++ - QMessageBox消失

serialization - JSON.Net 引用变为空

c# - 将值从字符串转换为流时出错

protocol-buffers - grpc Protobuf 3 嵌套消息定义

protocol-buffers - 为什么 protobuf FieldMask 使用字段名称而不是字段编号?

c++ - 开场流量不好?

c++ - 为什么数组没有形成?

c# - 将 dataGridView 序列化为 JSON

go - 解码Protobuf文字

c++ - 一个互斥锁与多个互斥锁。线程池用哪个好?