Boost.Serialization 和 Boost.Python 双向序列化

6 投票
2 回答
3812 浏览
提问于 2025-04-17 01:18

我有一个使用了Boost.Serialization的C++库。我正在用Boost.Python为这个库创建Python绑定。对于如何为Boost.Python制作一个使用Boost.Serialization的序列化工具,方法比较清楚(就是用Boost.Serialization把数据保存成字符串,然后把这个字符串返回给Python)。

我想要的正好相反:给定一个boost::python::object,我想要一个serialize(...)函数,这个函数会调用Python的pickle.dumps()函数,并把得到的字符串进行序列化。(想象一下有一个std::vector<boost::python::object>,在我序列化这个向量的时候,Boost.Serialization会调用辅助的serialize()函数。)这样做可能吗?更好的是,能不能使用cPickle而不把控制权交给Python解释器?

2 个回答

0

如果你的对象是一个原生的 Python 对象,那么使用 pickle.dumps() 就可以了。

另一方面,如果你有一个 std::vector,那就意味着你在同时使用 C++ 和 Python。这时候你需要像下面这样注册 std::vector:

using PyVec = std::vector<boost::python::object>;
boost::python::_class<PyVec, boost::noncopyable>
    ("PyVec", "My vector of PyObjects", boost::python::init<>() )
    .enable_pickling()
    .def_pickle( py_vec_pickle_suit() );

然后,当然你还需要定义一个 pickle suit。不过这会比较麻烦。

总结一下:直接使用 boost::python::list,然后对它调用 dump 就可以了。

0

这是我用来对boost::mersenne_twister实例进行序列化和反序列化的代码。

typedef boost::mt19937 rng_t;

struct mt_pickle_suite : bp::pickle_suite {

  static bp::object getstate (const rng_t& rng) {
    std::ostringstream os;
    boost::archive::binary_oarchive oa(os);
    oa << rng;
    return bp::str (os.str());
  }

static void
  setstate(rng_t& rng, bp::object entries) {
    bp::str s = bp::extract<bp::str> (entries)();
    std::string st = bp::extract<std::string> (s)();
    std::istringstream is (st);

    boost::archive::binary_iarchive ia (is);
    ia >> rng;
  }
};

撰写回答