简体   繁体   English

Boost.Serialization 和 Boost.Python 双向泡菜

[英]Boost.Serialization and Boost.Python two-way pickle

I have a C++ library that uses Boost.Serialization.我有一个使用 Boost.Serialization 的 C++ 库。 I'm creating Python bindings for this library using Boost.Python.我正在使用 Boost.Python 为这个库创建 Python 绑定。 It's fairly clear how to make a pickle suite for Boost.Python that uses Boost.Serialization (save to a string using Boost.Serialization, and return that string to Python).如何为使用 Boost.Serialization 的 Boost.Python 创建一个 pickle 套件(使用 Boost.Serialization 保存到一个字符串,然后将该字符串返回给 Python)是相当清楚的。

What I want is the reverse: given a boost::python::object , I want to have a serialize(...) function that would call Python's pickle.dumps() function and serialize the resulting string.我想要的是相反的:给定一个boost::python::object ,我想要一个serialize(...)函数来调用 Python 的pickle.dumps()函数并序列化结果字符串。 (Imagine an std::vector<boost::python::object> . As I serialize this vector, Boost.Serialization would call the auxiliary serialize() function.) Is this possible? (想象一个std::vector<boost::python::object> 。当我序列化这个向量时,Boost.Serialization 会调用辅助serialize()函数。)这可能吗? Better yet, is it possible to use cPickle and bypass giving the control to the Python interpreter?更好的是,是否可以使用cPickle并绕过将控制权交给 Python 解释器?

Here is the code I use to pickle/unpickle instance of boost::mersenne_twister这是我用来pickle/unpickle 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;
  }
};

If your object is a native python object, then pickle.dumps() will do the trick.如果您的对象是本机 Python 对象,那么 pickle.dumps() 可以解决问题。

In the other hand, if you have a std::vector, then you are mixing c++ and python.另一方面,如果你有一个 std::vector,那么你就是在混合 c++ 和 python。 For that you will need to register the std::vector like:为此,您需要注册 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() );

Then, of course you will need to define a pickle suit.那么,当然你需要定义一个泡菜套装。 But that is too cumbersome.但这太麻烦了。

TL;DR: Use boost::python::list instead and call dump over it. TL;DR:改用 boost::python::list 并在其上调用 dump。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM